7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-07 17:15:31 +00:00

add sentry-native files missed in earlier commit

This commit is contained in:
Marek Roszko 2023-12-18 22:10:23 -05:00
parent 5341af1a55
commit d6d25c030e
40 changed files with 2891 additions and 0 deletions

View 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_ */

View 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_ */

View 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_ */

View File

@ -0,0 +1 @@
* @getsentry/owners-native

View File

@ -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())

View 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);
}

View 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;
}

View 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;
}

View File

@ -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_

View File

@ -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_

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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_

Some files were not shown because too many files have changed in this diff Show More