add sentry-native files missed in earlier commit
This commit is contained in:
parent
5341af1a55
commit
d6d25c030e
16
thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/arm/_types.h
vendored
Normal file
16
thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/arm/_types.h
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2007 Apple Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef _BSD_ARM__TYPES_H_
|
||||
#define _BSD_ARM__TYPES_H_
|
||||
|
||||
#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
|
||||
|
||||
|
||||
typedef long __darwin_intptr_t;
|
||||
typedef unsigned int __darwin_natural_t;
|
||||
|
||||
|
||||
#endif /* defined (__arm__) || defined (__arm64__) || defined (__aarch64__) */
|
||||
|
||||
#endif /* _BSD_ARM__TYPES_H_ */
|
74
thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/boolean.h
vendored
Normal file
74
thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/boolean.h
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2007 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. The rights granted to you under the License
|
||||
* may not be used to create, or enable the creation or redistribution of,
|
||||
* unlawful or unlicensed copies of an Apple operating system, or to
|
||||
* circumvent, violate, or enable the circumvention or violation of, any
|
||||
* terms of an Apple operating system software license agreement.
|
||||
*
|
||||
* Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* @OSF_COPYRIGHT@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*/
|
||||
/*
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: boolean.h
|
||||
*
|
||||
* Boolean type, for ARM.
|
||||
*/
|
||||
|
||||
#ifndef _MACH_ARM_BOOLEAN_H_
|
||||
#define _MACH_ARM_BOOLEAN_H_
|
||||
|
||||
#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
|
||||
|
||||
typedef int boolean_t;
|
||||
|
||||
#endif /* defined (__arm__) || defined (__arm64__) */
|
||||
|
||||
#endif /* _MACH_ARM_BOOLEAN_H_ */
|
159
thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/vm_types.h
vendored
Normal file
159
thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/vm_types.h
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2007 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. The rights granted to you under the License
|
||||
* may not be used to create, or enable the creation or redistribution of,
|
||||
* unlawful or unlicensed copies of an Apple operating system, or to
|
||||
* circumvent, violate, or enable the circumvention or violation of, any
|
||||
* terms of an Apple operating system software license agreement.
|
||||
*
|
||||
* Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* @OSF_COPYRIGHT@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*/
|
||||
/*
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: vm_types.h
|
||||
* Author: Avadis Tevanian, Jr.
|
||||
* Date: 1985
|
||||
*
|
||||
* Header file for VM data types. ARM version.
|
||||
*/
|
||||
|
||||
#ifndef _MACH_ARM_VM_TYPES_H_
|
||||
#define _MACH_ARM_VM_TYPES_H_
|
||||
|
||||
#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
|
||||
|
||||
#ifndef ASSEMBLER
|
||||
|
||||
#include <arm/_types.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/*
|
||||
* natural_t and integer_t are Mach's legacy types for machine-
|
||||
* independent integer types (unsigned, and signed, respectively).
|
||||
* Their original purpose was to define other types in a machine/
|
||||
* compiler independent way.
|
||||
*
|
||||
* They also had an implicit "same size as pointer" characteristic
|
||||
* to them (i.e. Mach's traditional types are very ILP32 or ILP64
|
||||
* centric). We will likely support x86 ABIs that do not follow
|
||||
* either ofthese models (specifically LP64). Therefore, we had to
|
||||
* make a choice between making these types scale with pointers or stay
|
||||
* tied to integers. Because their use is predominantly tied to
|
||||
* to the size of an integer, we are keeping that association and
|
||||
* breaking free from pointer size guarantees.
|
||||
*
|
||||
* New use of these types is discouraged.
|
||||
*/
|
||||
typedef __darwin_natural_t natural_t;
|
||||
typedef int integer_t;
|
||||
|
||||
/*
|
||||
* A vm_offset_t is a type-neutral pointer,
|
||||
* e.g. an offset into a virtual memory space.
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
typedef uintptr_t vm_offset_t ;
|
||||
typedef uintptr_t vm_size_t;
|
||||
|
||||
typedef uint64_t mach_vm_address_t ;
|
||||
typedef uint64_t mach_vm_offset_t ;
|
||||
typedef uint64_t mach_vm_size_t;
|
||||
|
||||
typedef uint64_t vm_map_offset_t ;
|
||||
typedef uint64_t vm_map_address_t ;
|
||||
typedef uint64_t vm_map_size_t;
|
||||
#else
|
||||
typedef natural_t vm_offset_t ;
|
||||
/*
|
||||
* A vm_size_t is the proper type for e.g.
|
||||
* expressing the difference between two
|
||||
* vm_offset_t entities.
|
||||
*/
|
||||
typedef natural_t vm_size_t;
|
||||
|
||||
/*
|
||||
* This new type is independent of a particular vm map's
|
||||
* implementation size - and represents appropriate types
|
||||
* for all possible maps. This is used for interfaces
|
||||
* where the size of the map is not known - or we don't
|
||||
* want to have to distinguish.
|
||||
*/
|
||||
typedef uint64_t mach_vm_address_t ;
|
||||
typedef uint64_t mach_vm_offset_t ;
|
||||
typedef uint64_t mach_vm_size_t;
|
||||
|
||||
typedef uint32_t vm_map_offset_t ;
|
||||
typedef uint32_t vm_map_address_t ;
|
||||
typedef uint32_t vm_map_size_t;
|
||||
#endif /* __LP64__ */
|
||||
|
||||
|
||||
typedef uint32_t vm32_offset_t;
|
||||
typedef uint32_t vm32_address_t;
|
||||
typedef uint32_t vm32_size_t;
|
||||
|
||||
typedef vm_offset_t mach_port_context_t;
|
||||
|
||||
#ifdef MACH_KERNEL_PRIVATE
|
||||
typedef vm32_offset_t mach_port_context32_t;
|
||||
typedef mach_vm_offset_t mach_port_context64_t;
|
||||
#endif
|
||||
|
||||
#endif /* ASSEMBLER */
|
||||
|
||||
/*
|
||||
* If composing messages by hand (please do not)
|
||||
*/
|
||||
#define MACH_MSG_TYPE_INTEGER_T MACH_MSG_TYPE_INTEGER_32
|
||||
|
||||
#endif /* defined (__arm__) || defined (__arm64__) || defined (__aarch64__) */
|
||||
|
||||
#endif /* _MACH_ARM_VM_TYPES_H_ */
|
|
@ -0,0 +1 @@
|
|||
* @getsentry/owners-native
|
|
@ -0,0 +1,350 @@
|
|||
#!/usr/bin/env vpython3
|
||||
# Copyright 2023 The Chromium Authors
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
#
|
||||
# Generates a single BUILD.gn file with build targets generated using the
|
||||
# manifest files in the SDK.
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
|
||||
DIR_SRC_ROOT = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
|
||||
|
||||
def GetHostOS():
|
||||
"""Get host operating system."""
|
||||
|
||||
host_platform = sys.platform
|
||||
if host_platform.startswith('linux'):
|
||||
return 'linux'
|
||||
if host_platform.startswith('darwin'):
|
||||
return 'mac'
|
||||
raise Exception('Unsupported host platform: %s' % host_platform)
|
||||
|
||||
|
||||
# Inserted at the top of the generated BUILD.gn file.
|
||||
_GENERATED_PREAMBLE = """# DO NOT EDIT! This file was generated by
|
||||
# //build/fuchsia/gen_build_def.py.
|
||||
# Any changes made to this file will be discarded.
|
||||
|
||||
import("//third_party/fuchsia/sdk/{host_os}-amd64/build/fidl_library.gni")
|
||||
import("//third_party/fuchsia/sdk/{host_os}-amd64/build/fuchsia_sdk_pkg.gni")
|
||||
|
||||
""".format(host_os=GetHostOS())
|
||||
|
||||
SDK_ROOT = os.path.join(DIR_SRC_ROOT, 'third_party', 'fuchsia', 'sdk',
|
||||
f'{GetHostOS()}-amd64')
|
||||
|
||||
|
||||
def ReformatTargetName(dep_name):
|
||||
""""Substitutes characters in |dep_name| which are not valid in GN target
|
||||
names (e.g. dots become hyphens)."""
|
||||
return dep_name
|
||||
|
||||
|
||||
def FormatGNTarget(fields):
|
||||
"""Returns a GN target definition as a string.
|
||||
|
||||
|fields|: The GN fields to include in the target body.
|
||||
'target_name' and 'type' are mandatory."""
|
||||
|
||||
output = '%s("%s") {\n' % (fields['type'], fields['target_name'])
|
||||
del fields['target_name']
|
||||
del fields['type']
|
||||
|
||||
# Ensure that fields with no ordering requirement are sorted.
|
||||
for field in ['sources', 'public_deps']:
|
||||
if field in fields:
|
||||
fields[field].sort()
|
||||
|
||||
for key, val in fields.items():
|
||||
if isinstance(val, str):
|
||||
val_serialized = '\"%s\"' % val
|
||||
elif isinstance(val, list):
|
||||
# Serialize a list of strings in the prettiest possible manner.
|
||||
if len(val) == 0:
|
||||
val_serialized = '[]'
|
||||
elif len(val) == 1:
|
||||
val_serialized = '[ \"%s\" ]' % val[0]
|
||||
else:
|
||||
val_serialized = '[\n ' + ',\n '.join(['\"%s\"' % x
|
||||
for x in val]) + '\n ]'
|
||||
else:
|
||||
raise Exception('Could not serialize %r' % val)
|
||||
|
||||
output += ' %s = %s\n' % (key, val_serialized)
|
||||
output += '}'
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def MetaRootRelativePaths(sdk_relative_paths, meta_root):
|
||||
return [os.path.relpath(path, meta_root) for path in sdk_relative_paths]
|
||||
|
||||
|
||||
def ConvertCommonFields(json):
|
||||
"""Extracts fields from JSON manifest data which are used across all
|
||||
target types. Note that FIDL packages do their own processing."""
|
||||
|
||||
meta_root = json['root']
|
||||
|
||||
converted = {'target_name': ReformatTargetName(json['name'])}
|
||||
|
||||
if 'deps' in json:
|
||||
converted['public_deps'] = MetaRootRelativePaths(json['deps'],
|
||||
os.path.dirname(meta_root))
|
||||
|
||||
# FIDL bindings dependencies are relative to the "fidl" sub-directory.
|
||||
if 'fidl_binding_deps' in json:
|
||||
for entry in json['fidl_binding_deps']:
|
||||
converted['public_deps'] += MetaRootRelativePaths([
|
||||
'fidl/' + dep + ':' + os.path.basename(dep) + '_' +
|
||||
entry['binding_type'] for dep in entry['deps']
|
||||
], meta_root)
|
||||
|
||||
return converted
|
||||
|
||||
|
||||
def ConvertFidlLibrary(json):
|
||||
"""Converts a fidl_library manifest entry to a GN target.
|
||||
|
||||
Arguments:
|
||||
json: The parsed manifest JSON.
|
||||
Returns:
|
||||
The GN target definition, represented as a string."""
|
||||
|
||||
meta_root = json['root']
|
||||
|
||||
converted = ConvertCommonFields(json)
|
||||
converted['type'] = 'fidl_library'
|
||||
converted['sources'] = MetaRootRelativePaths(json['sources'], meta_root)
|
||||
converted['library_name'] = json['name']
|
||||
|
||||
return converted
|
||||
|
||||
|
||||
def ConvertCcPrebuiltLibrary(json):
|
||||
"""Converts a cc_prebuilt_library manifest entry to a GN target.
|
||||
|
||||
Arguments:
|
||||
json: The parsed manifest JSON.
|
||||
Returns:
|
||||
The GN target definition, represented as a string."""
|
||||
|
||||
meta_root = json['root']
|
||||
|
||||
converted = ConvertCommonFields(json)
|
||||
converted['type'] = 'fuchsia_sdk_pkg'
|
||||
|
||||
converted['sources'] = MetaRootRelativePaths(json['headers'], meta_root)
|
||||
|
||||
converted['include_dirs'] = MetaRootRelativePaths([json['include_dir']],
|
||||
meta_root)
|
||||
|
||||
if json['format'] == 'shared':
|
||||
converted['shared_libs'] = [json['name']]
|
||||
else:
|
||||
converted['static_libs'] = [json['name']]
|
||||
|
||||
return converted
|
||||
|
||||
|
||||
def ConvertCcSourceLibrary(json):
|
||||
"""Converts a cc_source_library manifest entry to a GN target.
|
||||
|
||||
Arguments:
|
||||
json: The parsed manifest JSON.
|
||||
Returns:
|
||||
The GN target definition, represented as a string."""
|
||||
|
||||
meta_root = json['root']
|
||||
|
||||
converted = ConvertCommonFields(json)
|
||||
converted['type'] = 'fuchsia_sdk_pkg'
|
||||
|
||||
# Headers and source file paths can be scattered across "sources", "headers",
|
||||
# and "files". Merge them together into one source list.
|
||||
converted['sources'] = MetaRootRelativePaths(json['sources'], meta_root)
|
||||
if 'headers' in json:
|
||||
converted['sources'] += MetaRootRelativePaths(json['headers'], meta_root)
|
||||
if 'files' in json:
|
||||
converted['sources'] += MetaRootRelativePaths(json['files'], meta_root)
|
||||
converted['sources'] = list(set(converted['sources']))
|
||||
|
||||
converted['include_dirs'] = MetaRootRelativePaths([json['include_dir']],
|
||||
meta_root)
|
||||
|
||||
return converted
|
||||
|
||||
|
||||
def ConvertLoadableModule(json):
|
||||
"""Converts a loadable module manifest entry to GN targets.
|
||||
|
||||
Arguments:
|
||||
json: The parsed manifest JSON.
|
||||
Returns:
|
||||
A list of GN target definitions."""
|
||||
|
||||
name = json['name']
|
||||
if name != 'vulkan_layers':
|
||||
raise RuntimeError('Unsupported loadable_module: %s' % name)
|
||||
|
||||
# Copy resources and binaries
|
||||
resources = json['resources']
|
||||
|
||||
binaries = json['binaries']
|
||||
|
||||
def _filename_no_ext(name):
|
||||
return os.path.splitext(os.path.basename(name))[0]
|
||||
|
||||
# Pair each json resource with its corresponding binary. Each such pair
|
||||
# is a "layer". We only need to check one arch because each arch has the
|
||||
# same list of binaries.
|
||||
arch = next(iter(binaries))
|
||||
binary_names = binaries[arch]
|
||||
local_pkg = json['root']
|
||||
vulkan_targets = []
|
||||
|
||||
for res in resources:
|
||||
layer_name = _filename_no_ext(res)
|
||||
|
||||
# Filter binaries for a matching name.
|
||||
filtered = [n for n in binary_names if _filename_no_ext(n) == layer_name]
|
||||
|
||||
if not filtered:
|
||||
# If the binary could not be found then do not generate a
|
||||
# target for this layer. The missing targets will cause a
|
||||
# mismatch with the "golden" outputs.
|
||||
continue
|
||||
|
||||
# Replace hardcoded arch in the found binary filename.
|
||||
binary = filtered[0].replace('/' + arch + '/', "/${target_cpu}/")
|
||||
|
||||
target = {}
|
||||
target['name'] = layer_name
|
||||
target['config'] = os.path.relpath(res, start=local_pkg)
|
||||
target['binary'] = os.path.relpath(binary, start=local_pkg)
|
||||
|
||||
vulkan_targets.append(target)
|
||||
|
||||
converted = []
|
||||
all_target = {}
|
||||
all_target['target_name'] = 'all'
|
||||
all_target['type'] = 'group'
|
||||
all_target['data_deps'] = []
|
||||
for target in vulkan_targets:
|
||||
config_target = {}
|
||||
config_target['target_name'] = target['name'] + '_config'
|
||||
config_target['type'] = 'copy'
|
||||
config_target['sources'] = [target['config']]
|
||||
config_target['outputs'] = ['${root_gen_dir}/' + target['config']]
|
||||
converted.append(config_target)
|
||||
lib_target = {}
|
||||
lib_target['target_name'] = target['name'] + '_lib'
|
||||
lib_target['type'] = 'copy'
|
||||
lib_target['sources'] = [target['binary']]
|
||||
lib_target['outputs'] = ['${root_out_dir}/lib/{{source_file_part}}']
|
||||
converted.append(lib_target)
|
||||
group_target = {}
|
||||
group_target['target_name'] = target['name']
|
||||
group_target['type'] = 'group'
|
||||
group_target['data_deps'] = [
|
||||
':' + target['name'] + '_config', ':' + target['name'] + '_lib'
|
||||
]
|
||||
converted.append(group_target)
|
||||
all_target['data_deps'].append(':' + target['name'])
|
||||
converted.append(all_target)
|
||||
return converted
|
||||
|
||||
|
||||
def ConvertNoOp(json):
|
||||
"""Null implementation of a conversion function. No output is generated."""
|
||||
|
||||
return None
|
||||
|
||||
|
||||
"""Maps manifest types to conversion functions."""
|
||||
_CONVERSION_FUNCTION_MAP = {
|
||||
'fidl_library': ConvertFidlLibrary,
|
||||
'cc_source_library': ConvertCcSourceLibrary,
|
||||
'cc_prebuilt_library': ConvertCcPrebuiltLibrary,
|
||||
'loadable_module': ConvertLoadableModule,
|
||||
|
||||
# No need to build targets for these types yet.
|
||||
'companion_host_tool': ConvertNoOp,
|
||||
'component_manifest': ConvertNoOp,
|
||||
'config': ConvertNoOp,
|
||||
'dart_library': ConvertNoOp,
|
||||
'data': ConvertNoOp,
|
||||
'device_profile': ConvertNoOp,
|
||||
'documentation': ConvertNoOp,
|
||||
'ffx_tool': ConvertNoOp,
|
||||
'host_tool': ConvertNoOp,
|
||||
'image': ConvertNoOp,
|
||||
'sysroot': ConvertNoOp,
|
||||
}
|
||||
|
||||
|
||||
def ConvertMeta(meta_path):
|
||||
parsed = json.load(open(meta_path))
|
||||
if 'type' not in parsed:
|
||||
return
|
||||
|
||||
convert_function = _CONVERSION_FUNCTION_MAP.get(parsed['type'])
|
||||
if convert_function is None:
|
||||
logging.warning('Unexpected SDK artifact type %s in %s.' %
|
||||
(parsed['type'], meta_path))
|
||||
return
|
||||
|
||||
converted = convert_function(parsed)
|
||||
if not converted:
|
||||
return
|
||||
output_path = os.path.join(os.path.dirname(meta_path), 'BUILD.gn')
|
||||
if os.path.exists(output_path):
|
||||
os.unlink(output_path)
|
||||
with open(output_path, 'w') as buildfile:
|
||||
buildfile.write(_GENERATED_PREAMBLE)
|
||||
|
||||
# Loadable modules have multiple targets
|
||||
if convert_function != ConvertLoadableModule:
|
||||
buildfile.write(FormatGNTarget(converted) + '\n\n')
|
||||
else:
|
||||
for target in converted:
|
||||
buildfile.write(FormatGNTarget(target) + '\n\n')
|
||||
|
||||
|
||||
def ProcessSdkManifest():
|
||||
toplevel_meta = json.load(
|
||||
open(os.path.join(SDK_ROOT, 'meta', 'manifest.json')))
|
||||
|
||||
for part in toplevel_meta['parts']:
|
||||
meta_path = os.path.join(SDK_ROOT, part['meta'])
|
||||
ConvertMeta(meta_path)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
# Exit if there's no Fuchsia support for this platform.
|
||||
try:
|
||||
GetHostOS()
|
||||
except:
|
||||
logging.warning('Fuchsia SDK is not supported on this platform.')
|
||||
return 0
|
||||
|
||||
# TODO(crbug/1432399): Remove this when links to these files inside the sdk
|
||||
# directory have been redirected.
|
||||
shutil.copytree(os.path.join(DIR_SRC_ROOT, 'third_party', 'fuchsia-gn-sdk',
|
||||
'src'),
|
||||
os.path.join(SDK_ROOT, 'build'),
|
||||
dirs_exist_ok=True)
|
||||
|
||||
ProcessSdkManifest()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
95
thirdparty/sentry-native/external/crashpad/handler/win/heap_corrupting_program.cc
vendored
Normal file
95
thirdparty/sentry-native/external/crashpad/handler/win/heap_corrupting_program.cc
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
// Copyright 2023 The Crashpad Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "client/crashpad_client.h"
|
||||
#include "util/misc/paths.h"
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
// We set up a program that crashes with a heap corruption exception.
|
||||
// STATUS_HEAP_CORRUPTION (0xC0000374 3221226356).
|
||||
namespace crashpad {
|
||||
namespace {
|
||||
|
||||
void HeapCorruptionCrash() {
|
||||
__try {
|
||||
HANDLE heap = ::HeapCreate(0, 0, 0);
|
||||
CHECK(heap);
|
||||
CHECK(HeapSetInformation(
|
||||
heap, HeapEnableTerminationOnCorruption, nullptr, 0));
|
||||
void* addr = ::HeapAlloc(heap, 0, 0x1000);
|
||||
CHECK(addr);
|
||||
// Corrupt heap header.
|
||||
char* addr_mutable = reinterpret_cast<char*>(addr);
|
||||
memset(addr_mutable - sizeof(addr), 0xCC, sizeof(addr));
|
||||
|
||||
HeapFree(heap, 0, addr);
|
||||
HeapDestroy(heap);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
// Heap corruption exception should never be caught.
|
||||
CHECK(false);
|
||||
}
|
||||
// Should never reach here.
|
||||
abort();
|
||||
}
|
||||
|
||||
int CrashyMain(int argc, wchar_t* argv[]) {
|
||||
static CrashpadClient* client = new crashpad::CrashpadClient();
|
||||
|
||||
if (argc == 2) {
|
||||
// We call this from end_to_end_test.py.
|
||||
if (!client->SetHandlerIPCPipe(argv[1])) {
|
||||
LOG(ERROR) << "SetHandler";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else if (argc == 3) {
|
||||
// This is helpful for debugging.
|
||||
if (!client->StartHandler(base::FilePath(argv[1]),
|
||||
base::FilePath(argv[2]),
|
||||
base::FilePath(),
|
||||
std::string(),
|
||||
std::map<std::string, std::string>(),
|
||||
std::vector<std::string>(),
|
||||
false,
|
||||
true)) {
|
||||
LOG(ERROR) << "StartHandler";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// Got to have a handler & registration.
|
||||
if (!client->WaitForHandlerStart(10000)) {
|
||||
LOG(ERROR) << "Handler failed to start";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Usage: %ls <server_pipe_name>\n", argv[0]);
|
||||
fprintf(stderr, " %ls <handler_path> <database_path>\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
HeapCorruptionCrash();
|
||||
|
||||
LOG(ERROR) << "Invalid type or exception failed.";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace crashpad
|
||||
|
||||
int wmain(int argc, wchar_t* argv[]) {
|
||||
return crashpad::CrashyMain(argc, argv);
|
||||
}
|
BIN
thirdparty/sentry-native/external/crashpad/snapshot/ios/testdata/crash-c44acfcbccd8c7a8
vendored
Normal file
BIN
thirdparty/sentry-native/external/crashpad/snapshot/ios/testdata/crash-c44acfcbccd8c7a8
vendored
Normal file
Binary file not shown.
84
thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getitimer.c
vendored
Normal file
84
thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getitimer.c
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* Copyright 2022 Google LLC
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test_skel.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// We need an invalid timer value. The assert()'s below should
|
||||
// be static asserts but it is not available in older C versions.
|
||||
#define kInvalidTimer 9999
|
||||
assert(kInvalidTimer != ITIMER_REAL);
|
||||
assert(kInvalidTimer != ITIMER_VIRTUAL);
|
||||
assert(kInvalidTimer != ITIMER_PROF);
|
||||
|
||||
// This should fail with EINVAL.
|
||||
struct kernel_itimerval curr_itimer;
|
||||
assert(sys_getitimer(kInvalidTimer, &curr_itimer) == -1);
|
||||
assert(errno == EINVAL);
|
||||
|
||||
// Create a read-only page.
|
||||
size_t page_size = getpagesize();
|
||||
void* read_only_page = sys_mmap(NULL, page_size, PROT_READ,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
assert(read_only_page != MAP_FAILED);
|
||||
|
||||
// This should fail with EFAULT.
|
||||
assert(sys_getitimer(ITIMER_REAL,
|
||||
(struct kernel_itimerval*) read_only_page) == -1);
|
||||
assert(errno == EFAULT);
|
||||
|
||||
// This should complete without an error.
|
||||
assert(sys_getitimer(ITIMER_REAL, &curr_itimer) == 0);
|
||||
|
||||
// Set up a real time timer with very long interval and value so that
|
||||
// we do not need to handle SIGALARM in test.
|
||||
struct kernel_itimerval new_itimer;
|
||||
const time_t kIntervalSec = 60 * 60 * 24 * 365; // One year.
|
||||
const long kIntervalUSec = 123;
|
||||
new_itimer.it_interval.tv_sec = kIntervalSec;
|
||||
new_itimer.it_interval.tv_usec = kIntervalUSec;
|
||||
new_itimer.it_value = new_itimer.it_interval;
|
||||
assert(sys_setitimer(ITIMER_REAL, &new_itimer, NULL) == 0);
|
||||
|
||||
assert(sys_getitimer(ITIMER_REAL, &curr_itimer) == 0);
|
||||
assert(kernel_timeval_eq(&curr_itimer.it_interval, &new_itimer.it_interval));
|
||||
|
||||
// Disable timer.
|
||||
struct kernel_itimerval empty_itimer;
|
||||
empty_itimer.it_interval.tv_sec = 0;
|
||||
empty_itimer.it_interval.tv_usec = 0;
|
||||
empty_itimer.it_value = empty_itimer.it_interval;
|
||||
assert(sys_setitimer(ITIMER_REAL, &empty_itimer, NULL) == 0);
|
||||
|
||||
// We should read back an empty itimer.
|
||||
assert(sys_getitimer(ITIMER_REAL, &curr_itimer) == 0);
|
||||
assert(kernel_itimerval_eq(&curr_itimer, &empty_itimer));
|
||||
|
||||
return 0;
|
||||
}
|
90
thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/setitimer.c
vendored
Normal file
90
thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/setitimer.c
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* Copyright 2022 Google LLC
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test_skel.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// We need an invalid timer value. The assert()'s below should
|
||||
// be static asserts but it is not avalible in older C versions.
|
||||
#define kInvalidTimer 9999
|
||||
assert(kInvalidTimer != ITIMER_REAL);
|
||||
assert(kInvalidTimer != ITIMER_VIRTUAL);
|
||||
assert(kInvalidTimer != ITIMER_PROF);
|
||||
|
||||
// Invalid timer returns EINVAL.
|
||||
assert(sys_setitimer(kInvalidTimer, NULL, NULL) == -1);
|
||||
assert(errno == EINVAL);
|
||||
|
||||
const int kSignal = SIGALRM;
|
||||
const size_t kSigsetSize = sizeof(struct kernel_sigset_t);
|
||||
|
||||
// Block SIGALRM.
|
||||
struct kernel_sigset_t sigalarm_only;
|
||||
struct kernel_sigset_t old_sigset;
|
||||
assert(sys_sigemptyset(&sigalarm_only) == 0);
|
||||
assert(sys_sigaddset(&sigalarm_only, kSignal) == 0);
|
||||
assert(sys_rt_sigprocmask(SIG_BLOCK, &sigalarm_only, &old_sigset,
|
||||
kSigsetSize) == 0);
|
||||
|
||||
// Set up a real time timer.
|
||||
struct kernel_itimerval new_itimer = {};
|
||||
const long kIntervalUSec = 123;
|
||||
new_itimer.it_interval.tv_sec = 0;
|
||||
new_itimer.it_interval.tv_usec = kIntervalUSec;
|
||||
new_itimer.it_value = new_itimer.it_interval;
|
||||
assert(sys_setitimer(ITIMER_REAL, &new_itimer, NULL) == 0);
|
||||
|
||||
// Wait for alarm.
|
||||
struct timespec timeout;
|
||||
const unsigned long kNanoSecsPerSec = 1000000000;
|
||||
const unsigned long kNanoSecsPerMicroSec = 1000;
|
||||
|
||||
// Use a timeout 3 times of the timer interval.
|
||||
unsigned long duration_ns = kIntervalUSec * kNanoSecsPerMicroSec * 3;
|
||||
timeout.tv_sec = duration_ns / kNanoSecsPerSec ;
|
||||
timeout.tv_nsec = duration_ns % kNanoSecsPerSec;
|
||||
|
||||
int sig;
|
||||
do {
|
||||
sig = sys_sigtimedwait(&sigalarm_only, NULL, &timeout);
|
||||
} while (sig == -1 && errno == EINTR);
|
||||
assert(sig == kSignal);
|
||||
|
||||
// Disable timer, check saving of old timer value.
|
||||
struct kernel_itimerval empty_itimer = {};
|
||||
struct kernel_itimerval old_itimer;
|
||||
empty_itimer.it_interval.tv_sec = 0;
|
||||
empty_itimer.it_interval.tv_usec = 0;
|
||||
empty_itimer.it_value = empty_itimer.it_interval;
|
||||
|
||||
assert(sys_setitimer(ITIMER_REAL, &empty_itimer, &old_itimer) == 0);
|
||||
assert(kernel_timeval_eq(&old_itimer.it_interval, &new_itimer.it_interval));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
// Copyright 2021 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BASE_APPLE_BRIDGING_H_
|
||||
#define BASE_APPLE_BRIDGING_H_
|
||||
|
||||
#include <CoreText/CoreText.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include "base/apple/scoped_cftyperef.h"
|
||||
#include "base/check.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#import <AppKit/AppKit.h>
|
||||
#endif
|
||||
|
||||
// These functions convert pointers of bridged CFTypes to NSTypes and
|
||||
// vice-versa. They come in two flavors: those that transfer ownership
|
||||
// (`OwnershipCast`) and those that just convert the pointer (`PtrCast`).
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// Ownership transference (as in `CFBridgingRetain`/`Release`):
|
||||
// CFStringRef cf_string = CFStringCreateWithCString(...);
|
||||
// NSString* ns_string = CFToNSOwnershipCast(cf_string);
|
||||
// // At this point, `cf_string` does not need releasing.
|
||||
//
|
||||
// NSString* ns_string = [[NSString alloc] initWithString:...];
|
||||
// CFStringRef cf_string = NSToCFOwnershipCast(ns_string);
|
||||
// // At this point, `cf_string` must be released.
|
||||
//
|
||||
// Pointer conversion (as in `__bridge`):
|
||||
// // `cf_data` is some `CFDataRef` from somewhere.
|
||||
// NSImage* ns_image = [[NSImage alloc] initWithData:CFToNSPtrCast(cf_data)];
|
||||
//
|
||||
// // `ns_data` is some `NSData *` from somewhere.
|
||||
// SecKeyRef sec_key = SecKeyCreateFromData(..., NSToCFPtrCast(ns_data), ...);
|
||||
//
|
||||
// The reason to use these functions (rather than using `__bridge` and
|
||||
// `CFBridgingRetain`/`Release`) is because they are type-safe. The OS-provided
|
||||
// bridging calls do not type check, while these calls do the appropriate type
|
||||
// checking via the magic of macros.
|
||||
//
|
||||
// Implementation note: Why not templates? Type checking in Core Foundation
|
||||
// involves functions named in a specific pattern, and only macro token pasting
|
||||
// works for this purpose.
|
||||
|
||||
#define CF_TO_NS_CAST_IMPL(TypeCF, TypeNS) \
|
||||
namespace base::apple { \
|
||||
inline TypeNS* _Nullable CFToNSOwnershipCast( \
|
||||
TypeCF##Ref CF_CONSUMED _Nullable cf_val) { \
|
||||
DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \
|
||||
return (__bridge_transfer TypeNS*)cf_val; \
|
||||
} \
|
||||
inline CF_RETURNS_RETAINED TypeCF##Ref _Nullable NSToCFOwnershipCast( \
|
||||
TypeNS* _Nullable ns_val) { \
|
||||
TypeCF##Ref cf_val = (__bridge_retained TypeCF##Ref)ns_val; \
|
||||
DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \
|
||||
return cf_val; \
|
||||
} \
|
||||
inline TypeNS* _Nullable CFToNSPtrCast(TypeCF##Ref _Nullable cf_val) { \
|
||||
DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \
|
||||
return (__bridge TypeNS*)cf_val; \
|
||||
} \
|
||||
inline TypeCF##Ref _Nullable NSToCFPtrCast(TypeNS* _Nullable ns_val) { \
|
||||
TypeCF##Ref cf_val = (__bridge TypeCF##Ref)ns_val; \
|
||||
DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \
|
||||
return cf_val; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CF_TO_NS_MUTABLE_CAST_IMPL(name) \
|
||||
CF_TO_NS_CAST_IMPL(CF##name, NS##name) \
|
||||
namespace base::apple { \
|
||||
inline NSMutable##name* _Nullable CFToNSOwnershipCast( \
|
||||
CFMutable##name##Ref CF_CONSUMED _Nullable cf_val) { \
|
||||
DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \
|
||||
return (__bridge_transfer NSMutable##name*)cf_val; \
|
||||
} \
|
||||
inline CF_RETURNS_RETAINED \
|
||||
CFMutable##name##Ref _Nullable NSToCFOwnershipCast( \
|
||||
NSMutable##name* _Nullable ns_val) { \
|
||||
CFMutable##name##Ref cf_val = \
|
||||
(__bridge_retained CFMutable##name##Ref)ns_val; \
|
||||
DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \
|
||||
return cf_val; \
|
||||
} \
|
||||
inline NSMutable##name* _Nullable CFToNSPtrCast( \
|
||||
CFMutable##name##Ref _Nullable cf_val) { \
|
||||
DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \
|
||||
return (__bridge NSMutable##name*)cf_val; \
|
||||
} \
|
||||
inline CFMutable##name##Ref _Nullable NSToCFPtrCast( \
|
||||
NSMutable##name* _Nullable ns_val) { \
|
||||
CFMutable##name##Ref cf_val = (__bridge CFMutable##name##Ref)ns_val; \
|
||||
DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \
|
||||
return cf_val; \
|
||||
} \
|
||||
}
|
||||
|
||||
// List of toll-free bridged types taken from:
|
||||
// https://web.archive.org/web/20111124025525/http://www.cocoadev.com/index.pl?TollFreeBridged
|
||||
// https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFDesignConcepts/Articles/tollFreeBridgedTypes.html#//apple_ref/doc/uid/TP40010677-SW4
|
||||
|
||||
// Foundation
|
||||
CF_TO_NS_MUTABLE_CAST_IMPL(Array)
|
||||
CF_TO_NS_MUTABLE_CAST_IMPL(AttributedString)
|
||||
CF_TO_NS_CAST_IMPL(CFCalendar, NSCalendar)
|
||||
CF_TO_NS_MUTABLE_CAST_IMPL(CharacterSet)
|
||||
CF_TO_NS_MUTABLE_CAST_IMPL(Data)
|
||||
CF_TO_NS_CAST_IMPL(CFDate, NSDate)
|
||||
CF_TO_NS_MUTABLE_CAST_IMPL(Dictionary)
|
||||
CF_TO_NS_CAST_IMPL(CFError, NSError)
|
||||
CF_TO_NS_CAST_IMPL(CFLocale, NSLocale)
|
||||
CF_TO_NS_CAST_IMPL(CFNumber, NSNumber)
|
||||
CF_TO_NS_CAST_IMPL(CFRunLoopTimer, NSTimer)
|
||||
CF_TO_NS_CAST_IMPL(CFTimeZone, NSTimeZone)
|
||||
CF_TO_NS_MUTABLE_CAST_IMPL(Set)
|
||||
CF_TO_NS_CAST_IMPL(CFReadStream, NSInputStream)
|
||||
CF_TO_NS_CAST_IMPL(CFWriteStream, NSOutputStream)
|
||||
CF_TO_NS_MUTABLE_CAST_IMPL(String)
|
||||
CF_TO_NS_CAST_IMPL(CFURL, NSURL)
|
||||
|
||||
// AppKit / UIKit
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
CF_TO_NS_CAST_IMPL(CTFont, UIFont)
|
||||
#else
|
||||
CF_TO_NS_CAST_IMPL(CTFont, NSFont)
|
||||
#endif // BUILDFLAG(IS_IOS)
|
||||
|
||||
#undef CF_TO_NS_CAST_IMPL
|
||||
#undef CF_TO_NS_MUTABLE_CAST_IMPL
|
||||
|
||||
#endif // BASE_APPLE_BRIDGING_H_
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright 2008 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MINI_CHROMIUM_BASE_APPLE_FOUNDATION_UTIL_H_
|
||||
#define MINI_CHROMIUM_BASE_APPLE_FOUNDATION_UTIL_H_
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
#include <CoreText/CoreText.h>
|
||||
#else
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
#if defined(__OBJC__)
|
||||
#import <Foundation/Foundation.h>
|
||||
#else // defined(__OBJC__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif // defined(__OBJC__)
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
|
||||
// CFCast<>() and CFCastStrict<>() cast a basic CFTypeRef to a more
|
||||
// specific CoreFoundation type. The compatibility of the passed
|
||||
// object is found by comparing its opaque type against the
|
||||
// requested type identifier. If the supplied object is not
|
||||
// compatible with the requested return type, CFCast<>() returns
|
||||
// NULL and CFCastStrict<>() will DCHECK. Providing a NULL pointer
|
||||
// to either variant results in NULL being returned without
|
||||
// triggering any DCHECK.
|
||||
//
|
||||
// Example usage:
|
||||
// CFNumberRef some_number = base::apple::CFCast<CFNumberRef>(
|
||||
// CFArrayGetValueAtIndex(array, index));
|
||||
//
|
||||
// CFTypeRef hello = CFSTR("hello world");
|
||||
// CFStringRef some_string = base::apple::CFCastStrict<CFStringRef>(hello);
|
||||
|
||||
template <typename T>
|
||||
T CFCast(const CFTypeRef& cf_val);
|
||||
|
||||
template <typename T>
|
||||
T CFCastStrict(const CFTypeRef& cf_val);
|
||||
|
||||
#define CF_CAST_DECL(TypeCF) \
|
||||
template <> \
|
||||
TypeCF##Ref CFCast<TypeCF##Ref>(const CFTypeRef& cf_val); \
|
||||
\
|
||||
template <> \
|
||||
TypeCF##Ref CFCastStrict<TypeCF##Ref>(const CFTypeRef& cf_val)
|
||||
|
||||
CF_CAST_DECL(CFArray);
|
||||
CF_CAST_DECL(CFBag);
|
||||
CF_CAST_DECL(CFBoolean);
|
||||
CF_CAST_DECL(CFData);
|
||||
CF_CAST_DECL(CFDate);
|
||||
CF_CAST_DECL(CFDictionary);
|
||||
CF_CAST_DECL(CFNull);
|
||||
CF_CAST_DECL(CFNumber);
|
||||
CF_CAST_DECL(CFSet);
|
||||
CF_CAST_DECL(CFString);
|
||||
CF_CAST_DECL(CFURL);
|
||||
CF_CAST_DECL(CFUUID);
|
||||
|
||||
CF_CAST_DECL(CGColor);
|
||||
|
||||
CF_CAST_DECL(CTFont);
|
||||
CF_CAST_DECL(CTRun);
|
||||
|
||||
#if !BUILDFLAG(IS_IOS)
|
||||
CF_CAST_DECL(SecACL);
|
||||
CF_CAST_DECL(SecTrustedApplication);
|
||||
#endif
|
||||
|
||||
#undef CF_CAST_DECL
|
||||
|
||||
#if defined(__OBJC__)
|
||||
|
||||
// ObjCCast<>() and ObjCCastStrict<>() cast a basic id to a more
|
||||
// specific (NSObject-derived) type. The compatibility of the passed
|
||||
// object is found by checking if it's a kind of the requested type
|
||||
// identifier. If the supplied object is not compatible with the
|
||||
// requested return type, ObjCCast<>() returns nil and
|
||||
// ObjCCastStrict<>() will DCHECK. Providing a nil pointer to either
|
||||
// variant results in nil being returned without triggering any DCHECK.
|
||||
//
|
||||
// The strict variant is useful when retrieving a value from a
|
||||
// collection which only has values of a specific type, e.g. an
|
||||
// NSArray of NSStrings. The non-strict variant is useful when
|
||||
// retrieving values from data that you can't fully control. For
|
||||
// example, a plist read from disk may be beyond your exclusive
|
||||
// control, so you'd only want to check that the values you retrieve
|
||||
// from it are of the expected types, but not crash if they're not.
|
||||
//
|
||||
// Example usage:
|
||||
// NSString* version = base::apple::ObjCCast<NSString>(
|
||||
// [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]);
|
||||
//
|
||||
// NSString* str = base::apple::ObjCCastStrict<NSString>(
|
||||
// [ns_arr_of_ns_strs objectAtIndex:0]);
|
||||
template <typename T>
|
||||
T* ObjCCast(id objc_val) {
|
||||
if ([objc_val isKindOfClass:[T class]]) {
|
||||
return reinterpret_cast<T*>(objc_val);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* ObjCCastStrict(id objc_val) {
|
||||
T* rv = ObjCCast<T>(objc_val);
|
||||
DCHECK(objc_val == nil || rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif // defined(__OBJC__)
|
||||
|
||||
} // namespace apple
|
||||
} // namespace base
|
||||
|
||||
#endif // MINI_CHROMIUM_BASE_APPLE_FOUNDATION_UTIL_H_
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2008 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/apple/foundation_util.h"
|
||||
|
||||
#if !BUILDFLAG(IS_IOS)
|
||||
extern "C" {
|
||||
CFTypeID SecACLGetTypeID();
|
||||
CFTypeID SecTrustedApplicationGetTypeID();
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
|
||||
#define CF_CAST_DEFN(TypeCF) \
|
||||
template <> \
|
||||
TypeCF##Ref CFCast<TypeCF##Ref>(const CFTypeRef& cf_val) { \
|
||||
if (cf_val == NULL) { \
|
||||
return NULL; \
|
||||
} \
|
||||
if (CFGetTypeID(cf_val) == TypeCF##GetTypeID()) { \
|
||||
return (TypeCF##Ref)(cf_val); \
|
||||
} \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
template <> \
|
||||
TypeCF##Ref CFCastStrict<TypeCF##Ref>(const CFTypeRef& cf_val) { \
|
||||
TypeCF##Ref rv = CFCast<TypeCF##Ref>(cf_val); \
|
||||
DCHECK(cf_val == NULL || rv); \
|
||||
return rv; \
|
||||
}
|
||||
|
||||
CF_CAST_DEFN(CFArray)
|
||||
CF_CAST_DEFN(CFBag)
|
||||
CF_CAST_DEFN(CFBoolean)
|
||||
CF_CAST_DEFN(CFData)
|
||||
CF_CAST_DEFN(CFDate)
|
||||
CF_CAST_DEFN(CFDictionary)
|
||||
CF_CAST_DEFN(CFNull)
|
||||
CF_CAST_DEFN(CFNumber)
|
||||
CF_CAST_DEFN(CFSet)
|
||||
CF_CAST_DEFN(CFString)
|
||||
CF_CAST_DEFN(CFURL)
|
||||
CF_CAST_DEFN(CFUUID)
|
||||
|
||||
CF_CAST_DEFN(CGColor)
|
||||
|
||||
CF_CAST_DEFN(CTFont)
|
||||
CF_CAST_DEFN(CTRun)
|
||||
|
||||
#if !BUILDFLAG(IS_IOS)
|
||||
CF_CAST_DEFN(SecACL)
|
||||
CF_CAST_DEFN(SecTrustedApplication)
|
||||
#endif
|
||||
|
||||
#undef CF_CAST_DEFN
|
||||
|
||||
} // namespace apple
|
||||
} // namespace base
|
|
@ -0,0 +1,84 @@
|
|||
// Copyright 2014 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/apple/mach_logging.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
#include "base/strings/stringprintf.h"
|
||||
|
||||
#if !BUILDFLAG(IS_IOS)
|
||||
#include <servers/bootstrap.h>
|
||||
#endif // !BUILDFLAG(IS_IOS)
|
||||
|
||||
namespace {
|
||||
|
||||
std::string FormatMachErrorNumber(mach_error_t mach_err) {
|
||||
// For the os/kern subsystem, give the error number in decimal as in
|
||||
// <mach/kern_return.h>. Otherwise, give it in hexadecimal to make it easier
|
||||
// to visualize the various bits. See <mach/error.h>.
|
||||
if (mach_err >= 0 && mach_err < KERN_RETURN_MAX) {
|
||||
return base::StringPrintf(" (%d)", mach_err);
|
||||
}
|
||||
return base::StringPrintf(" (0x%08x)", mach_err);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace logging {
|
||||
|
||||
MachLogMessage::MachLogMessage(const char* function,
|
||||
const char* file_path,
|
||||
int line,
|
||||
LogSeverity severity,
|
||||
mach_error_t mach_err)
|
||||
: LogMessage(function, file_path, line, severity), mach_err_(mach_err) {}
|
||||
|
||||
MachLogMessage::~MachLogMessage() {
|
||||
stream() << ": " << mach_error_string(mach_err_)
|
||||
<< FormatMachErrorNumber(mach_err_);
|
||||
}
|
||||
|
||||
#if !BUILDFLAG(IS_IOS)
|
||||
|
||||
BootstrapLogMessage::BootstrapLogMessage(const char* function,
|
||||
const char* file_path,
|
||||
int line,
|
||||
LogSeverity severity,
|
||||
kern_return_t bootstrap_err)
|
||||
: LogMessage(function, file_path, line, severity),
|
||||
bootstrap_err_(bootstrap_err) {}
|
||||
|
||||
BootstrapLogMessage::~BootstrapLogMessage() {
|
||||
stream() << ": " << bootstrap_strerror(bootstrap_err_);
|
||||
|
||||
switch (bootstrap_err_) {
|
||||
case BOOTSTRAP_SUCCESS:
|
||||
case BOOTSTRAP_NOT_PRIVILEGED:
|
||||
case BOOTSTRAP_NAME_IN_USE:
|
||||
case BOOTSTRAP_UNKNOWN_SERVICE:
|
||||
case BOOTSTRAP_SERVICE_ACTIVE:
|
||||
case BOOTSTRAP_BAD_COUNT:
|
||||
case BOOTSTRAP_NO_MEMORY:
|
||||
case BOOTSTRAP_NO_CHILDREN: {
|
||||
// Show known bootstrap errors in decimal because that's how they're
|
||||
// defined in <servers/bootstrap.h>.
|
||||
stream() << " (" << bootstrap_err_ << ")";
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
// bootstrap_strerror passes unknown errors to mach_error_string, so
|
||||
// format them as they would be if they were handled by
|
||||
// MachErrorMessage.
|
||||
stream() << FormatMachErrorNumber(bootstrap_err_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !BUILDFLAG(IS_IOS)
|
||||
|
||||
} // namespace logging
|
|
@ -0,0 +1,163 @@
|
|||
// Copyright 2014 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MINI_CHROMIUM_BASE_APPLE_MACH_LOGGING_H_
|
||||
#define MINI_CHROMIUM_BASE_APPLE_MACH_LOGGING_H_
|
||||
|
||||
#include <mach/mach.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
// Use the MACH_LOG family of macros along with a mach_error_t (kern_return_t)
|
||||
// containing a Mach error. The error value will be decoded so that logged
|
||||
// messages explain the error.
|
||||
//
|
||||
// Use the BOOTSTRAP_LOG family of macros specifically for errors that occur
|
||||
// while interoperating with the bootstrap subsystem. These errors will first
|
||||
// be looked up as bootstrap error messages. If no match is found, they will
|
||||
// be treated as generic Mach errors, as in MACH_LOG.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// kern_return_t kr = mach_timebase_info(&info);
|
||||
// if (kr != KERN_SUCCESS) {
|
||||
// MACH_LOG(ERROR, kr) << "mach_timebase_info";
|
||||
// }
|
||||
//
|
||||
// kr = vm_deallocate(task, address, size);
|
||||
// MACH_DCHECK(kr == KERN_SUCCESS, kr) << "vm_deallocate";
|
||||
|
||||
namespace logging {
|
||||
|
||||
class MachLogMessage : public logging::LogMessage {
|
||||
public:
|
||||
MachLogMessage(const char* function,
|
||||
const char* file_path,
|
||||
int line,
|
||||
LogSeverity severity,
|
||||
mach_error_t mach_err);
|
||||
|
||||
MachLogMessage(const MachLogMessage&) = delete;
|
||||
MachLogMessage& operator=(const MachLogMessage&) = delete;
|
||||
|
||||
~MachLogMessage();
|
||||
|
||||
private:
|
||||
mach_error_t mach_err_;
|
||||
};
|
||||
|
||||
} // namespace logging
|
||||
|
||||
#define MACH_LOG_STREAM(severity, mach_err) \
|
||||
COMPACT_GOOGLE_LOG_EX_##severity(MachLogMessage, mach_err).stream()
|
||||
#define MACH_VLOG_STREAM(verbose_level, mach_err) \
|
||||
logging::MachLogMessage( \
|
||||
__PRETTY_FUNCTION__, __FILE__, __LINE__, -verbose_level, mach_err) \
|
||||
.stream()
|
||||
|
||||
#define MACH_LOG(severity, mach_err) \
|
||||
LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), LOG_IS_ON(severity))
|
||||
#define MACH_LOG_IF(severity, condition, mach_err) \
|
||||
LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), \
|
||||
LOG_IS_ON(severity) && (condition))
|
||||
|
||||
#define MACH_VLOG(verbose_level, mach_err) \
|
||||
LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
|
||||
VLOG_IS_ON(verbose_level))
|
||||
#define MACH_VLOG_IF(verbose_level, condition, mach_err) \
|
||||
LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
|
||||
VLOG_IS_ON(verbose_level) && (condition))
|
||||
|
||||
#define MACH_CHECK(condition, mach_err) \
|
||||
LAZY_STREAM(MACH_LOG_STREAM(FATAL, mach_err), !(condition)) \
|
||||
<< "Check failed: " #condition << ". "
|
||||
|
||||
#define MACH_DLOG(severity, mach_err) \
|
||||
LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), DLOG_IS_ON(severity))
|
||||
#define MACH_DLOG_IF(severity, condition, mach_err) \
|
||||
LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), \
|
||||
DLOG_IS_ON(severity) && (condition))
|
||||
|
||||
#define MACH_DVLOG(verbose_level, mach_err) \
|
||||
LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
|
||||
DVLOG_IS_ON(verbose_level))
|
||||
#define MACH_DVLOG_IF(verbose_level, condition, mach_err) \
|
||||
LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
|
||||
DVLOG_IS_ON(verbose_level) && (condition))
|
||||
|
||||
#define MACH_DCHECK(condition, mach_err) \
|
||||
LAZY_STREAM(MACH_LOG_STREAM(FATAL, mach_err), DCHECK_IS_ON && !(condition)) \
|
||||
<< "Check failed: " #condition << ". "
|
||||
|
||||
#if !BUILDFLAG(IS_IOS)
|
||||
|
||||
namespace logging {
|
||||
|
||||
class BootstrapLogMessage : public logging::LogMessage {
|
||||
public:
|
||||
BootstrapLogMessage(const char* function,
|
||||
const char* file_path,
|
||||
int line,
|
||||
LogSeverity severity,
|
||||
kern_return_t bootstrap_err);
|
||||
|
||||
BootstrapLogMessage(const BootstrapLogMessage&) = delete;
|
||||
BootstrapLogMessage& operator=(const BootstrapLogMessage&) = delete;
|
||||
|
||||
~BootstrapLogMessage();
|
||||
|
||||
private:
|
||||
kern_return_t bootstrap_err_;
|
||||
};
|
||||
|
||||
} // namespace logging
|
||||
|
||||
#define BOOTSTRAP_LOG_STREAM(severity, bootstrap_err) \
|
||||
COMPACT_GOOGLE_LOG_EX_##severity(BootstrapLogMessage, bootstrap_err).stream()
|
||||
#define BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err) \
|
||||
logging::BootstrapLogMessage( \
|
||||
__PRETTY_FUNCTION__, __FILE__, __LINE__, -verbose_level, bootstrap_err) \
|
||||
.stream()
|
||||
|
||||
#define BOOTSTRAP_LOG(severity, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
|
||||
LOG_IS_ON(severity))
|
||||
#define BOOTSTRAP_LOG_IF(severity, condition, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
|
||||
LOG_IS_ON(severity) && (condition))
|
||||
|
||||
#define BOOTSTRAP_VLOG(verbose_level, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
|
||||
VLOG_IS_ON(verbose_level))
|
||||
#define BOOTSTRAP_VLOG_IF(verbose_level, condition, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
|
||||
VLOG_IS_ON(verbose_level) && (condition))
|
||||
|
||||
#define BOOTSTRAP_CHECK(condition, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_LOG_STREAM(FATAL, bootstrap_err), !(condition)) \
|
||||
<< "Check failed: " #condition << ". "
|
||||
|
||||
#define BOOTSTRAP_DLOG(severity, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
|
||||
DLOG_IS_ON(severity))
|
||||
#define BOOTSTRAP_DLOG_IF(severity, condition, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
|
||||
DLOG_IS_ON(severity) && (condition))
|
||||
|
||||
#define BOOTSTRAP_DVLOG(verbose_level, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
|
||||
DVLOG_IS_ON(verbose_level))
|
||||
#define BOOTSTRAP_DVLOG_IF(verbose_level, condition, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
|
||||
DVLOG_IS_ON(verbose_level) && (condition))
|
||||
|
||||
#define BOOTSTRAP_DCHECK(condition, bootstrap_err) \
|
||||
LAZY_STREAM(BOOTSTRAP_LOG_STREAM(FATAL, bootstrap_err), \
|
||||
DCHECK_IS_ON && !(condition)) \
|
||||
<< "Check failed: " #condition << ". "
|
||||
|
||||
#endif // !BUILDFLAG(IS_IOS)
|
||||
|
||||
#endif // MINI_CHROMIUM_BASE_APPLE_MACH_LOGGING_H_
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2006-2008 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MINI_CHROMIUM_BASE_APPLE_SCOPED_CFTYPEREF_H_
|
||||
#define MINI_CHROMIUM_BASE_APPLE_SCOPED_CFTYPEREF_H_
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#include "base/apple/scoped_typeref.h"
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename CFT>
|
||||
struct ScopedCFTypeRefTraits {
|
||||
static CFT InvalidValue() { return nullptr; }
|
||||
static CFT Retain(CFT object) {
|
||||
CFRetain(object);
|
||||
return object;
|
||||
}
|
||||
static void Release(CFT object) { CFRelease(object); }
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename CFT>
|
||||
using ScopedCFTypeRef =
|
||||
ScopedTypeRef<CFT, internal::ScopedCFTypeRefTraits<CFT>>;
|
||||
|
||||
} // namespace apple
|
||||
} // namespace base
|
||||
|
||||
#endif // MINI_CHROMIUM_BASE_APPLE_SCOPED_CFTYPEREF_H_
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2012 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/apple/scoped_mach_port.h"
|
||||
|
||||
#include "base/apple/mach_logging.h"
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
namespace internal {
|
||||
|
||||
void SendRightTraits::Free(mach_port_t port) {
|
||||
kern_return_t kr = mach_port_deallocate(mach_task_self(), port);
|
||||
MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_deallocate";
|
||||
}
|
||||
|
||||
void ReceiveRightTraits::Free(mach_port_t port) {
|
||||
kern_return_t kr =
|
||||
mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1);
|
||||
MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_mod_refs";
|
||||
}
|
||||
|
||||
void PortSetTraits::Free(mach_port_t port) {
|
||||
kern_return_t kr =
|
||||
mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_PORT_SET, -1);
|
||||
MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_mod_refs";
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace apple
|
||||
} // namespace base
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2012 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MINI_CHROMIUM_BASE_APPLE_SCOPED_MACH_PORT_H_
|
||||
#define MINI_CHROMIUM_BASE_APPLE_SCOPED_MACH_PORT_H_
|
||||
|
||||
#include <mach/mach.h>
|
||||
|
||||
#include "base/scoped_generic.h"
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
|
||||
namespace internal {
|
||||
|
||||
struct SendRightTraits {
|
||||
static mach_port_t InvalidValue() { return MACH_PORT_NULL; }
|
||||
static void Free(mach_port_t port);
|
||||
};
|
||||
|
||||
struct ReceiveRightTraits {
|
||||
static mach_port_t InvalidValue() { return MACH_PORT_NULL; }
|
||||
static void Free(mach_port_t port);
|
||||
};
|
||||
|
||||
struct PortSetTraits {
|
||||
static mach_port_t InvalidValue() { return MACH_PORT_NULL; }
|
||||
static void Free(mach_port_t port);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
using ScopedMachSendRight =
|
||||
ScopedGeneric<mach_port_t, internal::SendRightTraits>;
|
||||
using ScopedMachReceiveRight =
|
||||
ScopedGeneric<mach_port_t, internal::ReceiveRightTraits>;
|
||||
using ScopedMachPortSet = ScopedGeneric<mach_port_t, internal::PortSetTraits>;
|
||||
|
||||
} // namespace apple
|
||||
} // namespace base
|
||||
|
||||
#endif // MINI_CHROMIUM_BASE_APPLE_SCOPED_MACH_PORT_H_
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2014 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/apple/scoped_mach_vm.h"
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
|
||||
void ScopedMachVM::reset(vm_address_t address, vm_size_t size) {
|
||||
DCHECK(address % PAGE_SIZE == 0);
|
||||
DCHECK(size % PAGE_SIZE == 0);
|
||||
|
||||
if (size_) {
|
||||
if (address_ < address) {
|
||||
vm_deallocate(
|
||||
mach_task_self(), address_, std::min(size_, address - address_));
|
||||
}
|
||||
if (address_ + size_ > address + size) {
|
||||
vm_address_t deallocate_start = std::max(address_, address + size);
|
||||
vm_deallocate(mach_task_self(),
|
||||
deallocate_start,
|
||||
address_ + size_ - deallocate_start);
|
||||
}
|
||||
}
|
||||
|
||||
address_ = address;
|
||||
size_ = size;
|
||||
}
|
||||
|
||||
} // namespace apple
|
||||
} // namespace base
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2014 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MINI_CHROMIUM_BASE_APPLE_SCOPED_MACH_VM_H_
|
||||
#define MINI_CHROMIUM_BASE_APPLE_SCOPED_MACH_VM_H_
|
||||
|
||||
#include <mach/mach.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
// Use ScopedMachVM to supervise ownership of pages in the current process
|
||||
// through the Mach VM subsystem. Pages allocated with vm_allocate can be
|
||||
// released when exiting a scope with ScopedMachVM.
|
||||
//
|
||||
// The Mach VM subsystem operates on a page-by-page basis, and a single VM
|
||||
// allocation managed by a ScopedMachVM object may span multiple pages. As far
|
||||
// as Mach is concerned, allocated pages may be deallocated individually. This
|
||||
// is in contrast to higher-level allocators such as malloc, where the base
|
||||
// address of an allocation implies the size of an allocated block.
|
||||
// Consequently, it is not sufficient to just pass the base address of an
|
||||
// allocation to ScopedMachVM, it also needs to know the size of the
|
||||
// allocation. To avoid any confusion, both the base address and size must
|
||||
// be page-aligned.
|
||||
//
|
||||
// When dealing with Mach VM, base addresses will naturally be page-aligned,
|
||||
// but user-specified sizes may not be. If there's a concern that a size is
|
||||
// not page-aligned, use the mach_vm_round_page macro to correct it.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// vm_address_t address = 0;
|
||||
// vm_size_t size = 12345; // This requested size is not page-aligned.
|
||||
// kern_return_t kr =
|
||||
// vm_allocate(mach_task_self(), &address, size, VM_FLAGS_ANYWHERE);
|
||||
// if (kr != KERN_SUCCESS) {
|
||||
// return false;
|
||||
// }
|
||||
// ScopedMachVM vm_owner(address, mach_vm_round_page(size));
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
|
||||
class ScopedMachVM {
|
||||
public:
|
||||
explicit ScopedMachVM(vm_address_t address = 0, vm_size_t size = 0)
|
||||
: address_(address), size_(size) {
|
||||
DCHECK(address % PAGE_SIZE == 0);
|
||||
DCHECK(size % PAGE_SIZE == 0);
|
||||
}
|
||||
|
||||
ScopedMachVM(const ScopedMachVM&) = delete;
|
||||
ScopedMachVM& operator=(const ScopedMachVM&) = delete;
|
||||
|
||||
~ScopedMachVM() {
|
||||
if (size_) {
|
||||
vm_deallocate(mach_task_self(), address_, size_);
|
||||
}
|
||||
}
|
||||
|
||||
void reset(vm_address_t address = 0, vm_size_t size = 0);
|
||||
|
||||
vm_address_t address() const { return address_; }
|
||||
|
||||
vm_size_t size() const { return size_; }
|
||||
|
||||
void swap(ScopedMachVM& that) {
|
||||
std::swap(address_, that.address_);
|
||||
std::swap(size_, that.size_);
|
||||
}
|
||||
|
||||
void release() {
|
||||
address_ = 0;
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
vm_address_t address_;
|
||||
vm_size_t size_;
|
||||
};
|
||||
|
||||
} // namespace apple
|
||||
} // namespace base
|
||||
|
||||
#endif // MINI_CHROMIUM_BASE_APPLE_SCOPED_MACH_VM_H_
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2008 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MINI_CHROMIUM_BASE_APPLE_SCOPED_NSAUTORELEASE_POOL_H_
|
||||
#define MINI_CHROMIUM_BASE_APPLE_SCOPED_NSAUTORELEASE_POOL_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
|
||||
// On the Mac, ScopedNSAutoreleasePool creates an autorelease pool when
|
||||
// instantiated and pops it when destroyed. This allows an autorelease pool to
|
||||
// be maintained in ordinary C++ code without bringing in any direct Objective-C
|
||||
// dependency.
|
||||
//
|
||||
// On other platforms, ScopedNSAutoreleasePool is an empty object with no
|
||||
// effects. This allows it to be used directly in cross-platform code without
|
||||
// ugly #ifdefs.
|
||||
class ScopedNSAutoreleasePool {
|
||||
public:
|
||||
#if !BUILDFLAG(IS_APPLE)
|
||||
ScopedNSAutoreleasePool() {}
|
||||
void Recycle() {}
|
||||
#else // BUILDFLAG(IS_APPLE)
|
||||
ScopedNSAutoreleasePool();
|
||||
|
||||
ScopedNSAutoreleasePool(const ScopedNSAutoreleasePool&) = delete;
|
||||
ScopedNSAutoreleasePool& operator=(const ScopedNSAutoreleasePool&) = delete;
|
||||
|
||||
~ScopedNSAutoreleasePool();
|
||||
|
||||
// Clear out the pool in case its position on the stack causes it to be
|
||||
// alive for long periods of time (such as the entire length of the app).
|
||||
// Only use then when you're certain the items currently in the pool are
|
||||
// no longer needed.
|
||||
void Recycle();
|
||||
|
||||
private:
|
||||
void* autorelease_pool_;
|
||||
#endif // BUILDFLAG(IS_APPLE)
|
||||
};
|
||||
|
||||
} // namespace apple
|
||||
} // namespace base
|
||||
|
||||
#endif // MINI_CHROMIUM_BASE_APPLE_SCOPED_NSAUTORELEASE_POOL_H_
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2008 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/apple/scoped_nsautorelease_pool.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
// Note that this uses the direct runtime interface to the autorelease pool.
|
||||
// https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support
|
||||
// This is so this can work when compiled for ARC.
|
||||
|
||||
extern "C" {
|
||||
void* objc_autoreleasePoolPush(void);
|
||||
void objc_autoreleasePoolPop(void* pool);
|
||||
}
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
|
||||
ScopedNSAutoreleasePool::ScopedNSAutoreleasePool()
|
||||
: autorelease_pool_(objc_autoreleasePoolPush()) {}
|
||||
|
||||
ScopedNSAutoreleasePool::~ScopedNSAutoreleasePool() {
|
||||
objc_autoreleasePoolPop(autorelease_pool_);
|
||||
}
|
||||
|
||||
// Cycle the internal pool, allowing everything there to get cleaned up and
|
||||
// start anew.
|
||||
void ScopedNSAutoreleasePool::Recycle() {
|
||||
objc_autoreleasePoolPop(autorelease_pool_);
|
||||
autorelease_pool_ = objc_autoreleasePoolPush();
|
||||
}
|
||||
|
||||
} // namespace apple
|
||||
} // namespace base
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2014 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MINI_CHROMIUM_BASE_APPLE_SCOPED_TYPEREF_H_
|
||||
#define MINI_CHROMIUM_BASE_APPLE_SCOPED_TYPEREF_H_
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_policy.h"
|
||||
|
||||
namespace base {
|
||||
namespace apple {
|
||||
|
||||
template <typename T>
|
||||
struct ScopedTypeRefTraits;
|
||||
|
||||
template <typename T, typename Traits = ScopedTypeRefTraits<T>>
|
||||
class ScopedTypeRef {
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
ScopedTypeRef(
|
||||
T object = Traits::InvalidValue(),
|
||||
base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME)
|
||||
: object_(object) {
|
||||
if (object_ && policy == base::scoped_policy::RETAIN)
|
||||
object_ = Traits::Retain(object_);
|
||||
}
|
||||
|
||||
ScopedTypeRef(const ScopedTypeRef<T, Traits>& that) : object_(that.object_) {
|
||||
if (object_)
|
||||
object_ = Traits::Retain(object_);
|
||||
}
|
||||
|
||||
~ScopedTypeRef() {
|
||||
if (object_)
|
||||
Traits::Release(object_);
|
||||
}
|
||||
|
||||
ScopedTypeRef& operator=(const ScopedTypeRef<T, Traits>& that) {
|
||||
reset(that.get(), base::scoped_policy::RETAIN);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] T* InitializeInto() {
|
||||
DCHECK(!object_);
|
||||
return &object_;
|
||||
}
|
||||
|
||||
void reset(T object = Traits::InvalidValue(),
|
||||
base::scoped_policy::OwnershipPolicy policy =
|
||||
base::scoped_policy::ASSUME) {
|
||||
if (object && policy == base::scoped_policy::RETAIN)
|
||||
object = Traits::Retain(object);
|
||||
if (object_)
|
||||
Traits::Release(object_);
|
||||
object_ = object;
|
||||
}
|
||||
|
||||
bool operator==(T that) const { return object_ == that; }
|
||||
|
||||
bool operator!=(T that) const { return object_ != that; }
|
||||
|
||||
operator T() const { return object_; }
|
||||
|
||||
T get() const { return object_; }
|
||||
|
||||
void swap(ScopedTypeRef& that) {
|
||||
T temp = that.object_;
|
||||
that.object_ = object_;
|
||||
object_ = temp;
|
||||
}
|
||||
|
||||
[[nodiscard]] T release() {
|
||||
T temp = object_;
|
||||
object_ = Traits::InvalidValue();
|
||||
return temp;
|
||||
}
|
||||
|
||||
private:
|
||||
T object_;
|
||||
};
|
||||
|
||||
} // namespace apple
|
||||
} // namespace base
|
||||
|
||||
#endif // MINI_CHROMIUM_BASE_APPLE_SCOPED_TYPEREF_H_
|
|
@ -0,0 +1,155 @@
|
|||
// Copyright 2015 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/strings/pattern.h"
|
||||
|
||||
#include "base/third_party/icu/icu_utf.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr bool IsWildcard(base_icu::UChar32 character) {
|
||||
return character == '*' || character == '?';
|
||||
}
|
||||
|
||||
// Searches for the next subpattern of |pattern| in |string|, up to the given
|
||||
// |maximum_distance|. The subpattern extends from the start of |pattern| up to
|
||||
// the first wildcard character (or the end of the string). If the value of
|
||||
// |maximum_distance| is negative, the maximum distance is considered infinite.
|
||||
template <typename CHAR, typename NEXT>
|
||||
constexpr bool SearchForChars(const CHAR** pattern,
|
||||
const CHAR* pattern_end,
|
||||
const CHAR** string,
|
||||
const CHAR* string_end,
|
||||
int maximum_distance,
|
||||
NEXT next) {
|
||||
const CHAR* pattern_start = *pattern;
|
||||
const CHAR* string_start = *string;
|
||||
bool escape = false;
|
||||
while (true) {
|
||||
if (*pattern == pattern_end) {
|
||||
// If this is the end of the pattern, only accept the end of the string;
|
||||
// anything else falls through to the mismatch case.
|
||||
if (*string == string_end)
|
||||
return true;
|
||||
} else {
|
||||
// If we have found a wildcard, we're done.
|
||||
if (!escape && IsWildcard(**pattern))
|
||||
return true;
|
||||
|
||||
// Check if the escape character is found. If so, skip it and move to the
|
||||
// next character.
|
||||
if (!escape && **pattern == '\\') {
|
||||
escape = true;
|
||||
next(pattern, pattern_end);
|
||||
continue;
|
||||
}
|
||||
|
||||
escape = false;
|
||||
|
||||
if (*string == string_end)
|
||||
return false;
|
||||
|
||||
// Check if the chars match, if so, increment the ptrs.
|
||||
const CHAR* pattern_next = *pattern;
|
||||
const CHAR* string_next = *string;
|
||||
base_icu::UChar32 pattern_char = next(&pattern_next, pattern_end);
|
||||
if (pattern_char == next(&string_next, string_end) &&
|
||||
pattern_char != CBU_SENTINEL) {
|
||||
*pattern = pattern_next;
|
||||
*string = string_next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Mismatch. If we have reached the maximum distance, return false,
|
||||
// otherwise restart at the beginning of the pattern with the next character
|
||||
// in the string.
|
||||
// TODO(bauerb): This is a naive implementation of substring search, which
|
||||
// could be implemented with a more efficient algorithm, e.g.
|
||||
// Knuth-Morris-Pratt (at the expense of requiring preprocessing).
|
||||
if (maximum_distance == 0)
|
||||
return false;
|
||||
|
||||
// Because unlimited distance is represented as -1, this will never reach 0
|
||||
// and therefore fail the match above.
|
||||
maximum_distance--;
|
||||
*pattern = pattern_start;
|
||||
next(&string_start, string_end);
|
||||
*string = string_start;
|
||||
}
|
||||
}
|
||||
|
||||
// Consumes consecutive wildcard characters (? or *). Returns the maximum number
|
||||
// of characters matched by the sequence of wildcards, or -1 if the wildcards
|
||||
// match an arbitrary number of characters (which is the case if it contains at
|
||||
// least one *).
|
||||
template <typename CHAR, typename NEXT>
|
||||
constexpr int EatWildcards(const CHAR** pattern, const CHAR* end, NEXT next) {
|
||||
int num_question_marks = 0;
|
||||
bool has_asterisk = false;
|
||||
while (*pattern != end) {
|
||||
if (**pattern == '?') {
|
||||
num_question_marks++;
|
||||
} else if (**pattern == '*') {
|
||||
has_asterisk = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
next(pattern, end);
|
||||
}
|
||||
return has_asterisk ? -1 : num_question_marks;
|
||||
}
|
||||
|
||||
template <typename CHAR, typename NEXT>
|
||||
constexpr bool MatchPatternT(const CHAR* eval,
|
||||
const CHAR* eval_end,
|
||||
const CHAR* pattern,
|
||||
const CHAR* pattern_end,
|
||||
NEXT next) {
|
||||
do {
|
||||
int maximum_wildcard_length = EatWildcards(&pattern, pattern_end, next);
|
||||
if (!SearchForChars(&pattern, pattern_end, &eval, eval_end,
|
||||
maximum_wildcard_length, next)) {
|
||||
return false;
|
||||
}
|
||||
} while (pattern != pattern_end);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct NextCharUTF8 {
|
||||
base_icu::UChar32 operator()(const char** p, const char* end) {
|
||||
base_icu::UChar32 c;
|
||||
int offset = 0;
|
||||
CBU8_NEXT(reinterpret_cast<const uint8_t*>(*p), offset, end - *p, c);
|
||||
*p += offset;
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
struct NextCharUTF16 {
|
||||
base_icu::UChar32 operator()(const char16_t** p, const char16_t* end) {
|
||||
base_icu::UChar32 c;
|
||||
int offset = 0;
|
||||
CBU16_NEXT(*p, offset, end - *p, c);
|
||||
*p += offset;
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool MatchPattern(StringPiece eval, StringPiece pattern) {
|
||||
return MatchPatternT(eval.data(), eval.data() + eval.size(), pattern.data(),
|
||||
pattern.data() + pattern.size(), NextCharUTF8());
|
||||
}
|
||||
|
||||
bool MatchPattern(StringPiece16 eval, StringPiece16 pattern) {
|
||||
return MatchPatternT(eval.data(), eval.data() + eval.size(), pattern.data(),
|
||||
pattern.data() + pattern.size(), NextCharUTF16());
|
||||
}
|
||||
|
||||
} // namespace base
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2015 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BASE_STRINGS_PATTERN_H_
|
||||
#define BASE_STRINGS_PATTERN_H_
|
||||
|
||||
#include "base/strings/string_piece.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
// Returns true if the |string| passed in matches the |pattern|. The pattern
|
||||
// string can contain wildcards like * and ?.
|
||||
//
|
||||
// The backslash character (\) is an escape character for * and ?.
|
||||
// ? matches 0 or 1 character, while * matches 0 or more characters.
|
||||
bool MatchPattern(StringPiece string, StringPiece pattern);
|
||||
bool MatchPattern(StringPiece16 string, StringPiece16 pattern);
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_STRINGS_PATTERN_H_
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MINI_CHROMIUM_BASE_TYPES_CXX23_TO_UNDERLYING_H_
|
||||
#define MINI_CHROMIUM_BASE_TYPES_CXX23_TO_UNDERLYING_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace base {
|
||||
|
||||
// Implementation of C++23's std::to_underlying.
|
||||
//
|
||||
// Note: This has an additional `std::is_enum<EnumT>` requirement to be SFINAE
|
||||
// friendly prior to C++20.
|
||||
//
|
||||
// Reference: https://en.cppreference.com/w/cpp/utility/to_underlying
|
||||
template <typename EnumT, typename = std::enable_if_t<std::is_enum<EnumT>{}>>
|
||||
constexpr std::underlying_type_t<EnumT> to_underlying(EnumT e) noexcept {
|
||||
return static_cast<std::underlying_type_t<EnumT>>(e);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // MINI_CHROMIUM_BASE_TYPES_CXX23_TO_UNDERLYING_H_
|
147
thirdparty/sentry-native/external/crashpad/tools/dump_minidump_annotations.cc
vendored
Normal file
147
thirdparty/sentry-native/external/crashpad/tools/dump_minidump_annotations.cc
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
// Copyright 2023 The Crashpad Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "client/annotation.h"
|
||||
#include "util/file/file_reader.h"
|
||||
#include "snapshot/minidump/process_snapshot_minidump.h"
|
||||
#include "tools/tool_support.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace {
|
||||
|
||||
void Usage(const base::FilePath& me) {
|
||||
// clang-format off
|
||||
fprintf(stderr,
|
||||
"Usage: %" PRFilePath " [OPTION]... PATH\n"
|
||||
"Dump annotations from minidumps.\n"
|
||||
"\n"
|
||||
" --help display this help and exit\n"
|
||||
" --version output version information and exit\n",
|
||||
me.value().c_str());
|
||||
// clang-format on
|
||||
ToolSupport::UsageTail(me);
|
||||
}
|
||||
|
||||
struct Options {
|
||||
const char* minidump;
|
||||
};
|
||||
|
||||
int DumpMinidumpAnnotationsMain(int argc, char* argv[]) {
|
||||
const base::FilePath argv0(
|
||||
ToolSupport::CommandLineArgumentToFilePathStringType(argv[0]));
|
||||
const base::FilePath me(argv0.BaseName());
|
||||
|
||||
enum OptionFlags {
|
||||
// Long options without short equivalents.
|
||||
kOptionLastChar = 255,
|
||||
kOptionMinidump,
|
||||
|
||||
// Standard options.
|
||||
kOptionHelp = -2,
|
||||
kOptionVersion = -3,
|
||||
};
|
||||
|
||||
static constexpr option long_options[] = {
|
||||
{"minidump", required_argument, nullptr, kOptionMinidump},
|
||||
{"help", no_argument, nullptr, kOptionHelp},
|
||||
{"version", no_argument, nullptr, kOptionVersion},
|
||||
{nullptr, 0, nullptr, 0},
|
||||
};
|
||||
|
||||
Options options = {};
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt_long(argc, argv, "", long_options, nullptr)) != -1) {
|
||||
switch (opt) {
|
||||
case kOptionMinidump: {
|
||||
options.minidump = optarg;
|
||||
break;
|
||||
}
|
||||
case kOptionHelp: {
|
||||
Usage(me);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
case kOptionVersion: {
|
||||
ToolSupport::Version(me);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
default: {
|
||||
ToolSupport::UsageHint(me, nullptr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (!options.minidump) {
|
||||
ToolSupport::UsageHint(me, "--minidump is required");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
FileReader reader;
|
||||
if (!reader.Open(base::FilePath(
|
||||
ToolSupport::CommandLineArgumentToFilePathStringType(
|
||||
options.minidump)))) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ProcessSnapshotMinidump snapshot;
|
||||
if (!snapshot.Initialize(&reader)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (const ModuleSnapshot* module : snapshot.Modules()) {
|
||||
printf("Module: %s\n", module->Name().c_str());
|
||||
printf(" Simple Annotations\n");
|
||||
for (const auto& kv : module->AnnotationsSimpleMap()) {
|
||||
printf(" simple_annotations[\"%s\"] = %s\n",
|
||||
kv.first.c_str(), kv.second.c_str());
|
||||
}
|
||||
|
||||
printf(" Vectored Annotations\n");
|
||||
int index = 0;
|
||||
for (const std::string& annotation : module->AnnotationsVector()) {
|
||||
printf(" vectored_annotations[%d] = %s\n", index, annotation.c_str());
|
||||
index++;
|
||||
}
|
||||
|
||||
printf(" Annotation Objects\n");
|
||||
for (const AnnotationSnapshot& annotation : module->AnnotationObjects()) {
|
||||
printf(" annotation_objects[\"%s\"] = ", annotation.name.c_str());
|
||||
if (annotation.type != static_cast<uint16_t>(Annotation::Type::kString)) {
|
||||
|
||||
printf("<non-string value, not printing>\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string value(reinterpret_cast<const char*>(annotation.value.data()),
|
||||
annotation.value.size());
|
||||
|
||||
printf("%s\n", value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace crashpad
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
return crashpad::DumpMinidumpAnnotationsMain(argc, argv);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2023 The Crashpad Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include "util/linux/pac_helper.h"
|
||||
|
||||
#if defined(__has_feature)
|
||||
#define CRASHPAD_HAS_FEATURE(x) __has_feature(x)
|
||||
#else
|
||||
#define CRASHPAD_HAS_FEATURE(x) 0
|
||||
#endif
|
||||
|
||||
#if CRASHPAD_HAS_FEATURE(ptrauth_intrinsics)
|
||||
#include <ptrauth.h>
|
||||
#endif
|
||||
|
||||
#include "util/misc/address_types.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
VMAddress StripPACBits(VMAddress address) {
|
||||
#if CRASHPAD_HAS_FEATURE(ptrauth_intrinsics)
|
||||
address = ptrauth_strip(address, ptrauth_key_function_pointer);
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
// Strip any pointer authentication bits that are assigned to the address.
|
||||
register uintptr_t x30 __asm("x30") = address;
|
||||
asm("xpaclri" : "+r"(x30));
|
||||
address = x30;
|
||||
#endif
|
||||
return address;
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2023 The Crashpad Authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef CRASHPAD_UTIL_LINUX_PAC_HELPER_H_
|
||||
#define CRASHPAD_UTIL_LINUX_PAC_HELPER_H_
|
||||
|
||||
#include "util/misc/address_types.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief Strips PAC bits from an address
|
||||
VMAddress StripPACBits(VMAddress address);
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
|
||||
#endif // CRASHPAD_UTIL_LINUX_PAC_HELPER_H_
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <cxxabi.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef SENTRY_REMOVED
|
||||
#include <rustc_demangle.h>
|
||||
#endif //SENTRY_REMOVED
|
||||
|
||||
#include <unwindstack/Demangle.h>
|
||||
|
||||
namespace unwindstack {
|
||||
|
||||
std::string DemangleNameIfNeeded(const std::string& name) {
|
||||
if (name.length() < 2 || name[0] != '_') {
|
||||
return name;
|
||||
}
|
||||
|
||||
char* demangled_str = nullptr;
|
||||
if (name[1] == 'Z') {
|
||||
// Try to demangle C++ name.
|
||||
demangled_str = abi::__cxa_demangle(name.c_str(), nullptr, nullptr, nullptr);
|
||||
#ifdef SENTRY_REMOVED
|
||||
} else if (name[1] == 'R') {
|
||||
// Try to demangle rust name.
|
||||
demangled_str = rustc_demangle(name.c_str(), nullptr, nullptr, nullptr);
|
||||
#endif //SENTRY_REMOVED
|
||||
}
|
||||
|
||||
if (demangled_str == nullptr) {
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string demangled_name(demangled_str);
|
||||
free(demangled_str);
|
||||
return demangled_name;
|
||||
}
|
||||
|
||||
} // namespace unwindstack
|
25
thirdparty/sentry-native/external/libunwindstack-ndk/include/unwindstack/Demangle.h
vendored
Normal file
25
thirdparty/sentry-native/external/libunwindstack-ndk/include/unwindstack/Demangle.h
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace unwindstack {
|
||||
|
||||
std::string DemangleNameIfNeeded(const std::string& name);
|
||||
|
||||
} // namespace unwindstack
|
|
@ -0,0 +1,12 @@
|
|||
# Metadata information for this directory.
|
||||
#
|
||||
# For more information on DIR_METADATA files, see:
|
||||
# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/README.md
|
||||
#
|
||||
# For the schema of this file, see Metadata message:
|
||||
# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto
|
||||
|
||||
os: LINUX
|
||||
monorail {
|
||||
project: "linux-syscall-support"
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
Copyright 2005-2011 Google LLC
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
Neither the name of Google LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,2 @@
|
|||
mseaborn@chromium.org
|
||||
vapier@chromium.org
|
|
@ -0,0 +1,84 @@
|
|||
/* Copyright 2022 Google LLC
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test_skel.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// We need an invalid timer value. The assert()'s below should
|
||||
// be static asserts but it is not available in older C versions.
|
||||
#define kInvalidTimer 9999
|
||||
assert(kInvalidTimer != ITIMER_REAL);
|
||||
assert(kInvalidTimer != ITIMER_VIRTUAL);
|
||||
assert(kInvalidTimer != ITIMER_PROF);
|
||||
|
||||
// This should fail with EINVAL.
|
||||
struct kernel_itimerval curr_itimer;
|
||||
assert(sys_getitimer(kInvalidTimer, &curr_itimer) == -1);
|
||||
assert(errno == EINVAL);
|
||||
|
||||
// Create a read-only page.
|
||||
size_t page_size = getpagesize();
|
||||
void* read_only_page = sys_mmap(NULL, page_size, PROT_READ,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
assert(read_only_page != MAP_FAILED);
|
||||
|
||||
// This should fail with EFAULT.
|
||||
assert(sys_getitimer(ITIMER_REAL,
|
||||
(struct kernel_itimerval*) read_only_page) == -1);
|
||||
assert(errno == EFAULT);
|
||||
|
||||
// This should complete without an error.
|
||||
assert(sys_getitimer(ITIMER_REAL, &curr_itimer) == 0);
|
||||
|
||||
// Set up a real time timer with very long interval and value so that
|
||||
// we do not need to handle SIGALARM in test.
|
||||
struct kernel_itimerval new_itimer;
|
||||
const time_t kIntervalSec = 60 * 60 * 24 * 365; // One year.
|
||||
const long kIntervalUSec = 123;
|
||||
new_itimer.it_interval.tv_sec = kIntervalSec;
|
||||
new_itimer.it_interval.tv_usec = kIntervalUSec;
|
||||
new_itimer.it_value = new_itimer.it_interval;
|
||||
assert(sys_setitimer(ITIMER_REAL, &new_itimer, NULL) == 0);
|
||||
|
||||
assert(sys_getitimer(ITIMER_REAL, &curr_itimer) == 0);
|
||||
assert(kernel_timeval_eq(&curr_itimer.it_interval, &new_itimer.it_interval));
|
||||
|
||||
// Disable timer.
|
||||
struct kernel_itimerval empty_itimer;
|
||||
empty_itimer.it_interval.tv_sec = 0;
|
||||
empty_itimer.it_interval.tv_usec = 0;
|
||||
empty_itimer.it_value = empty_itimer.it_interval;
|
||||
assert(sys_setitimer(ITIMER_REAL, &empty_itimer, NULL) == 0);
|
||||
|
||||
// We should read back an empty itimer.
|
||||
assert(sys_getitimer(ITIMER_REAL, &curr_itimer) == 0);
|
||||
assert(kernel_itimerval_eq(&curr_itimer, &empty_itimer));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/* Copyright 2020 Google LLC
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test_skel.h"
|
||||
|
||||
#define BUFFER_SIZE 256
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char buffer[BUFFER_SIZE];
|
||||
// Zero it out so we can check later that it's at least not all 0s.
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
bool buffer_contains_all_zeros = true;
|
||||
|
||||
// Don't bother passing any flags. (If we're using lss, we might not have the
|
||||
// right header files with the flags defined anyway, and we'd have to copy
|
||||
// this in here too, and risk getting out of sync in yet another way.)
|
||||
const ssize_t r = sys_getrandom(buffer, BUFFER_SIZE, 0);
|
||||
|
||||
// Make sure it either worked, or that it's just not supported.
|
||||
assert(r == BUFFER_SIZE || errno == ENOSYS);
|
||||
|
||||
if (r == BUFFER_SIZE) {
|
||||
// If all the bytes are 0, it didn't really work.
|
||||
for (size_t i = 0; i < BUFFER_SIZE; ++i) {
|
||||
if (buffer[i] != 0) {
|
||||
buffer_contains_all_zeros = false;
|
||||
}
|
||||
}
|
||||
assert(!buffer_contains_all_zeros);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/* Copyright 2021 Google LLC
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test_skel.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int exit_status = 0;
|
||||
|
||||
// Get two unique paths to play with.
|
||||
char foo[] = "tempfile.XXXXXX";
|
||||
char bar[] = "tempfile.XXXXXX";
|
||||
int fd_foo = mkstemp(foo);
|
||||
int fd_bar = mkstemp(bar);
|
||||
assert(fd_foo != -1);
|
||||
assert(fd_bar != -1);
|
||||
|
||||
// Then delete foo.
|
||||
assert(sys_unlink(foo) == 0);
|
||||
|
||||
// Now make foo a symlink to bar.
|
||||
assert(symlink(bar, foo) == 0);
|
||||
|
||||
// Make sure sys_stat() and sys_lstat() implementation return different
|
||||
// information.
|
||||
|
||||
// We need to check our stat syscalls for EOVERFLOW, as sometimes the integer
|
||||
// types used in the stat structures are too small to fit the actual value.
|
||||
// E.g. on some systems st_ino is 32-bit, but some filesystems have 64-bit
|
||||
// inodes.
|
||||
|
||||
struct kernel_stat lstat_info;
|
||||
int rc = sys_lstat(foo, &lstat_info);
|
||||
if (rc < 0 && errno == EOVERFLOW) {
|
||||
// Bail out since we had an overflow in the stat structure.
|
||||
exit_status = SKIP_TEST_EXIT_STATUS;
|
||||
goto cleanup;
|
||||
}
|
||||
assert(rc == 0);
|
||||
|
||||
struct kernel_stat stat_info;
|
||||
rc = sys_stat(foo, &stat_info);
|
||||
if (rc < 0 && errno == EOVERFLOW) {
|
||||
// Bail out since we had an overflow in the stat structure.
|
||||
exit_status = SKIP_TEST_EXIT_STATUS;
|
||||
goto cleanup;
|
||||
}
|
||||
assert(rc == 0);
|
||||
|
||||
struct kernel_stat bar_stat_info;
|
||||
rc = sys_stat(bar, &bar_stat_info);
|
||||
if (rc < 0 && errno == EOVERFLOW) {
|
||||
// Bail out since we had an overflow in the stat structure.
|
||||
exit_status = SKIP_TEST_EXIT_STATUS;
|
||||
goto cleanup;
|
||||
}
|
||||
assert(rc == 0);
|
||||
|
||||
// lstat should produce information about a symlink.
|
||||
assert((lstat_info.st_mode & S_IFMT) == S_IFLNK);
|
||||
|
||||
// stat-ing foo and bar should produce the same inode.
|
||||
assert(stat_info.st_ino == bar_stat_info.st_ino);
|
||||
|
||||
// lstat-ing foo should give a different inode than stat-ing foo.
|
||||
assert(stat_info.st_ino != lstat_info.st_ino);
|
||||
|
||||
cleanup:
|
||||
sys_unlink(foo);
|
||||
sys_unlink(bar);
|
||||
return exit_status;
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/* Copyright 2022 Google LLC
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test_skel.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// We need an invalid timer value. The assert()'s below should
|
||||
// be static asserts but it is not avalible in older C versions.
|
||||
#define kInvalidTimer 9999
|
||||
assert(kInvalidTimer != ITIMER_REAL);
|
||||
assert(kInvalidTimer != ITIMER_VIRTUAL);
|
||||
assert(kInvalidTimer != ITIMER_PROF);
|
||||
|
||||
// Invalid timer returns EINVAL.
|
||||
assert(sys_setitimer(kInvalidTimer, NULL, NULL) == -1);
|
||||
assert(errno == EINVAL);
|
||||
|
||||
const int kSignal = SIGALRM;
|
||||
const size_t kSigsetSize = sizeof(struct kernel_sigset_t);
|
||||
|
||||
// Block SIGALRM.
|
||||
struct kernel_sigset_t sigalarm_only;
|
||||
struct kernel_sigset_t old_sigset;
|
||||
assert(sys_sigemptyset(&sigalarm_only) == 0);
|
||||
assert(sys_sigaddset(&sigalarm_only, kSignal) == 0);
|
||||
assert(sys_rt_sigprocmask(SIG_BLOCK, &sigalarm_only, &old_sigset,
|
||||
kSigsetSize) == 0);
|
||||
|
||||
// Set up a real time timer.
|
||||
struct kernel_itimerval new_itimer = {};
|
||||
const long kIntervalUSec = 123;
|
||||
new_itimer.it_interval.tv_sec = 0;
|
||||
new_itimer.it_interval.tv_usec = kIntervalUSec;
|
||||
new_itimer.it_value = new_itimer.it_interval;
|
||||
assert(sys_setitimer(ITIMER_REAL, &new_itimer, NULL) == 0);
|
||||
|
||||
// Wait for alarm.
|
||||
struct timespec timeout;
|
||||
const unsigned long kNanoSecsPerSec = 1000000000;
|
||||
const unsigned long kNanoSecsPerMicroSec = 1000;
|
||||
|
||||
// Use a timeout 3 times of the timer interval.
|
||||
unsigned long duration_ns = kIntervalUSec * kNanoSecsPerMicroSec * 3;
|
||||
timeout.tv_sec = duration_ns / kNanoSecsPerSec ;
|
||||
timeout.tv_nsec = duration_ns % kNanoSecsPerSec;
|
||||
|
||||
int sig;
|
||||
do {
|
||||
sig = sys_sigtimedwait(&sigalarm_only, NULL, &timeout);
|
||||
} while (sig == -1 && errno == EINTR);
|
||||
assert(sig == kSignal);
|
||||
|
||||
// Disable timer, check saving of old timer value.
|
||||
struct kernel_itimerval empty_itimer = {};
|
||||
struct kernel_itimerval old_itimer;
|
||||
empty_itimer.it_interval.tv_sec = 0;
|
||||
empty_itimer.it_interval.tv_usec = 0;
|
||||
empty_itimer.it_value = empty_itimer.it_interval;
|
||||
|
||||
assert(sys_setitimer(ITIMER_REAL, &empty_itimer, &old_itimer) == 0);
|
||||
assert(kernel_timeval_eq(&old_itimer.it_interval, &new_itimer.it_interval));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/* Copyright 2020 Google LLC
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test_skel.h"
|
||||
|
||||
void test_handler(int sig) {}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const size_t kSigsetSize = sizeof(struct kernel_sigset_t);
|
||||
struct kernel_sigaction action = {};
|
||||
// Invalid signal returns EINVAL.
|
||||
assert(sys_rt_sigaction(SIGKILL, &action, NULL, kSigsetSize) == -1);
|
||||
assert(errno == EINVAL);
|
||||
|
||||
// Set an action.
|
||||
action.sa_handler_ = test_handler;
|
||||
action.sa_flags = SA_SIGINFO;
|
||||
assert(sys_sigemptyset(&action.sa_mask) == 0);
|
||||
assert(sys_sigaddset(&action.sa_mask, SIGPIPE) == 0);
|
||||
assert(sys_rt_sigaction(SIGSEGV, &action, NULL, kSigsetSize) == 0);
|
||||
|
||||
// Retrieve the action.
|
||||
struct kernel_sigaction old_action = {};
|
||||
assert(sys_rt_sigaction(SIGSEGV, NULL, &old_action, kSigsetSize) == 0);
|
||||
assert(memcmp(&action, &old_action, sizeof(action)) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/* Copyright 2021 Google LLC
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test_skel.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int exit_status = 0;
|
||||
|
||||
// Get two unique paths to play with.
|
||||
char foo[] = "tempfile.XXXXXX";
|
||||
int fd_foo = mkstemp(foo);
|
||||
assert(fd_foo != -1);
|
||||
|
||||
// Make sure it exists.
|
||||
assert(access(foo, F_OK) == 0);
|
||||
|
||||
// Make sure sys_stat() and a libc stat() implementation return the same
|
||||
// information.
|
||||
struct stat libc_stat;
|
||||
assert(stat(foo, &libc_stat) == 0);
|
||||
|
||||
struct kernel_stat raw_stat;
|
||||
// We need to check our stat syscall for EOVERFLOW, as sometimes the integer
|
||||
// types used in the stat structures are too small to fit the actual value.
|
||||
// E.g. on some systems st_ino is 32-bit, but some filesystems have 64-bit
|
||||
// inodes.
|
||||
int rc = sys_stat(foo, &raw_stat);
|
||||
if (rc < 0 && errno == EOVERFLOW) {
|
||||
// Bail out since we had an overflow in the stat structure.
|
||||
exit_status = SKIP_TEST_EXIT_STATUS;
|
||||
goto cleanup;
|
||||
}
|
||||
assert(rc == 0);
|
||||
|
||||
assert(libc_stat.st_ino == raw_stat.st_ino);
|
||||
|
||||
|
||||
cleanup:
|
||||
sys_unlink(foo);
|
||||
return exit_status;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#include "sentry_options.h"
|
||||
#include "sentry_testsupport.h"
|
||||
|
||||
SENTRY_TEST(options_sdk_name_defaults)
|
||||
{
|
||||
sentry_options_t *options = sentry_options_new();
|
||||
// when nothing is set
|
||||
|
||||
// then both sdk name and user agent should default to the build time
|
||||
// directives
|
||||
TEST_CHECK_STRING_EQUAL(
|
||||
sentry_options_get_sdk_name(options), SENTRY_SDK_NAME);
|
||||
TEST_CHECK_STRING_EQUAL(
|
||||
sentry_options_get_user_agent(options), SENTRY_SDK_USER_AGENT);
|
||||
|
||||
sentry_options_free(options);
|
||||
}
|
||||
|
||||
SENTRY_TEST(options_sdk_name_custom)
|
||||
{
|
||||
sentry_options_t *options = sentry_options_new();
|
||||
|
||||
// when the sdk name is set to a custom string
|
||||
const int result
|
||||
= sentry_options_set_sdk_name(options, "sentry.native.android.flutter");
|
||||
|
||||
// both the sdk_name and user_agent should reflect this change
|
||||
TEST_CHECK_INT_EQUAL(result, 0);
|
||||
TEST_CHECK_STRING_EQUAL(
|
||||
sentry_options_get_sdk_name(options), "sentry.native.android.flutter");
|
||||
|
||||
TEST_CHECK_STRING_EQUAL(sentry_options_get_user_agent(options),
|
||||
"sentry.native.android.flutter/" SENTRY_SDK_VERSION);
|
||||
|
||||
sentry_options_free(options);
|
||||
}
|
||||
|
||||
SENTRY_TEST(options_sdk_name_invalid)
|
||||
{
|
||||
sentry_options_t *options = sentry_options_new();
|
||||
|
||||
// when the sdk name is set to an invalid value
|
||||
const char *sdk_name = NULL;
|
||||
const int result = sentry_options_set_sdk_name(options, sdk_name);
|
||||
|
||||
// then the value should be ignored
|
||||
TEST_CHECK_INT_EQUAL(result, 1);
|
||||
TEST_CHECK_STRING_EQUAL(
|
||||
sentry_options_get_sdk_name(options), SENTRY_SDK_NAME);
|
||||
TEST_CHECK_STRING_EQUAL(
|
||||
sentry_options_get_user_agent(options), SENTRY_SDK_USER_AGENT);
|
||||
|
||||
sentry_options_free(options);
|
||||
}
|
Loading…
Reference in New Issue