From d6d25c030e52a579e4b39c82abc0618bd65a9df5 Mon Sep 17 00:00:00 2001
From: Marek Roszko <mark.roszko@gmail.com>
Date: Mon, 18 Dec 2023 22:10:23 -0500
Subject: [PATCH] add sentry-native files missed in earlier commit

---
 .../src/third_party/mac_headers/arm/_types.h  |  16 +
 .../mac_headers/mach/arm/boolean.h            |  74 ++++
 .../mac_headers/mach/arm/vm_types.h           | 159 ++++++++
 .../external/crashpad/.github/CODEOWNERS      |   1 +
 .../crashpad/build/fuchsia/gen_build_defs.py  | 350 ++++++++++++++++++
 .../handler/win/heap_corrupting_program.cc    |  95 +++++
 .../ios/testdata/crash-c44acfcbccd8c7a8       | Bin 0 -> 972 bytes
 .../third_party/lss/lss/tests/getitimer.c     |  84 +++++
 .../third_party/lss/lss/tests/setitimer.c     |  90 +++++
 .../mini_chromium/base/apple/bridging.h       | 140 +++++++
 .../base/apple/foundation_util.h              | 124 +++++++
 .../base/apple/foundation_util.mm             |  62 ++++
 .../mini_chromium/base/apple/mach_logging.cc  |  84 +++++
 .../mini_chromium/base/apple/mach_logging.h   | 163 ++++++++
 .../base/apple/scoped_cftyperef.h             |  36 ++
 .../base/apple/scoped_mach_port.cc            |  32 ++
 .../base/apple/scoped_mach_port.h             |  43 +++
 .../base/apple/scoped_mach_vm.cc              |  32 ++
 .../mini_chromium/base/apple/scoped_mach_vm.h |  87 +++++
 .../base/apple/scoped_nsautorelease_pool.h    |  48 +++
 .../base/apple/scoped_nsautorelease_pool.mm   |  36 ++
 .../mini_chromium/base/apple/scoped_typeref.h |  87 +++++
 .../mini_chromium/base/strings/pattern.cc     | 155 ++++++++
 .../mini_chromium/base/strings/pattern.h      |  22 ++
 .../base/types/cxx23_to_underlying.h          |  25 ++
 .../tools/dump_minidump_annotations.cc        | 147 ++++++++
 .../crashpad/util/linux/pac_helper.cc         |  44 +++
 .../external/crashpad/util/linux/pac_helper.h |  29 ++
 .../external/libunwindstack-ndk/Demangle.cpp  |  55 +++
 .../include/unwindstack/Demangle.h            |  25 ++
 .../external/third_party/lss/DIR_METADATA     |  12 +
 .../external/third_party/lss/LICENSE          |  27 ++
 .../external/third_party/lss/OWNERS           |   2 +
 .../third_party/lss/tests/getitimer.c         |  84 +++++
 .../third_party/lss/tests/getrandom.c         |  59 +++
 .../external/third_party/lss/tests/lstat.c    |  97 +++++
 .../third_party/lss/tests/setitimer.c         |  90 +++++
 .../third_party/lss/tests/sigaction.c         |  54 +++
 .../external/third_party/lss/tests/stat.c     |  67 ++++
 .../sentry-native/tests/unit/test_options.c   |  54 +++
 40 files changed, 2891 insertions(+)
 create mode 100644 thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/arm/_types.h
 create mode 100644 thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/boolean.h
 create mode 100644 thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/vm_types.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/.github/CODEOWNERS
 create mode 100644 thirdparty/sentry-native/external/crashpad/build/fuchsia/gen_build_defs.py
 create mode 100644 thirdparty/sentry-native/external/crashpad/handler/win/heap_corrupting_program.cc
 create mode 100644 thirdparty/sentry-native/external/crashpad/snapshot/ios/testdata/crash-c44acfcbccd8c7a8
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getitimer.c
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/setitimer.c
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/bridging.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/foundation_util.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/foundation_util.mm
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/mach_logging.cc
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/mach_logging.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_cftyperef.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_port.cc
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_port.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_vm.cc
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_vm.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_nsautorelease_pool.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_nsautorelease_pool.mm
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_typeref.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/pattern.cc
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/pattern.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/types/cxx23_to_underlying.h
 create mode 100644 thirdparty/sentry-native/external/crashpad/tools/dump_minidump_annotations.cc
 create mode 100644 thirdparty/sentry-native/external/crashpad/util/linux/pac_helper.cc
 create mode 100644 thirdparty/sentry-native/external/crashpad/util/linux/pac_helper.h
 create mode 100644 thirdparty/sentry-native/external/libunwindstack-ndk/Demangle.cpp
 create mode 100644 thirdparty/sentry-native/external/libunwindstack-ndk/include/unwindstack/Demangle.h
 create mode 100644 thirdparty/sentry-native/external/third_party/lss/DIR_METADATA
 create mode 100644 thirdparty/sentry-native/external/third_party/lss/LICENSE
 create mode 100644 thirdparty/sentry-native/external/third_party/lss/OWNERS
 create mode 100644 thirdparty/sentry-native/external/third_party/lss/tests/getitimer.c
 create mode 100644 thirdparty/sentry-native/external/third_party/lss/tests/getrandom.c
 create mode 100644 thirdparty/sentry-native/external/third_party/lss/tests/lstat.c
 create mode 100644 thirdparty/sentry-native/external/third_party/lss/tests/setitimer.c
 create mode 100644 thirdparty/sentry-native/external/third_party/lss/tests/sigaction.c
 create mode 100644 thirdparty/sentry-native/external/third_party/lss/tests/stat.c
 create mode 100644 thirdparty/sentry-native/tests/unit/test_options.c

diff --git a/thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/arm/_types.h b/thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/arm/_types.h
new file mode 100644
index 0000000000..f464d6bd66
--- /dev/null
+++ b/thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/arm/_types.h
@@ -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_ */
\ No newline at end of file
diff --git a/thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/boolean.h b/thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/boolean.h
new file mode 100644
index 0000000000..d653a394cb
--- /dev/null
+++ b/thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/boolean.h
@@ -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_ */
\ No newline at end of file
diff --git a/thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/vm_types.h b/thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/vm_types.h
new file mode 100644
index 0000000000..3650a86907
--- /dev/null
+++ b/thirdparty/sentry-native/external/breakpad/src/third_party/mac_headers/mach/arm/vm_types.h
@@ -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_ */
\ No newline at end of file
diff --git a/thirdparty/sentry-native/external/crashpad/.github/CODEOWNERS b/thirdparty/sentry-native/external/crashpad/.github/CODEOWNERS
new file mode 100644
index 0000000000..7afbb99cb6
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/.github/CODEOWNERS
@@ -0,0 +1 @@
+*   @getsentry/owners-native
diff --git a/thirdparty/sentry-native/external/crashpad/build/fuchsia/gen_build_defs.py b/thirdparty/sentry-native/external/crashpad/build/fuchsia/gen_build_defs.py
new file mode 100644
index 0000000000..22414d1c10
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/build/fuchsia/gen_build_defs.py
@@ -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())
diff --git a/thirdparty/sentry-native/external/crashpad/handler/win/heap_corrupting_program.cc b/thirdparty/sentry-native/external/crashpad/handler/win/heap_corrupting_program.cc
new file mode 100644
index 0000000000..6c7c2cd5a6
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/handler/win/heap_corrupting_program.cc
@@ -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);
+}
diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/testdata/crash-c44acfcbccd8c7a8 b/thirdparty/sentry-native/external/crashpad/snapshot/ios/testdata/crash-c44acfcbccd8c7a8
new file mode 100644
index 0000000000000000000000000000000000000000..5e7eb83f33ee5a8d239aad283c6e7b2ffccdbb00
GIT binary patch
literal 972
zcmZWoO=uHA7@gV8q%|QVkV>kT^q?LpWJG9BRvVItU~57Wu|lD4HxqVEvb*eVOmZ>@
zBZ7sZBDQ+*Uk@HaJ@^M2FN#+|5D(sjRumKuo@AZb?5-hxFwDH~d+*IR!;Bw606{+>
zyctG!!x0DSvmJpg(@g*rv6Vr$!#=0<y#fKc<-t!9g?Bum<_O1Ew%L4mFN_|BM;)y@
zp$Gq^ICy`UiJ$nv5Hr5c0gi(gqG&a`({Yotg^7Y(>prtAv=VjO?7gM%YLs_KnL-g=
z{D;y-G<L=7$~iT>7Da2G!H3{}fUbK`U)TrG4G->lvmKyy4+chkv@c$ZLDY!3EwHVT
zIS6A2G~Hc8i&LD<XvN$V7;pEuUI3uyLD$1iDI6R~FfL8J2yQVk4V=`psw@hotSSax
z5Y-Y%2%3gds$vqwG;o@nA=R2jbeyXSW?9uYc6Be6cRYPpGq9YKRE1;<39VnM;W>F(
z7xY$NrBaoF^Tbf=x=84%u9$L-<W<$gbwkHhd6|uQK~{>APJ~iQB4UN;iBgNEC(<Y9
z(o2W)$@$EQZ2ss{E?GP>gO3}`^K{)XWkpmaqTq(ASForHhNKDY#@gz~&h7wu8T4+2
zo$?Vscq=0`!};JQkG}HmO*NHV3T^T33udChpe2{d)aV=Eb;>L~NylTbIrZL(e~ujN
z0C392(+u;@AJJySSHI5!@Z;EP``fe+Iru<-J~sv|%lZT2jxS~Y+Ms+lW<!(bEf+hU
kWs18$BVQOV>$`0Ga`v+TV6Q72no-kxFmQ1?#H!rLUwlur@Bjb+

literal 0
HcmV?d00001

diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getitimer.c b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getitimer.c
new file mode 100644
index 0000000000..860538a0fb
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getitimer.c
@@ -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;
+}
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/setitimer.c b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/setitimer.c
new file mode 100644
index 0000000000..dd2ccfe5c3
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/setitimer.c
@@ -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;
+}
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/bridging.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/bridging.h
new file mode 100644
index 0000000000..d5dde2d993
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/bridging.h
@@ -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_
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/foundation_util.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/foundation_util.h
new file mode 100644
index 0000000000..1654c8a1e2
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/foundation_util.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_
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/foundation_util.mm b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/foundation_util.mm
new file mode 100644
index 0000000000..b3cd7f6a9f
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/foundation_util.mm
@@ -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
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/mach_logging.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/mach_logging.cc
new file mode 100644
index 0000000000..d5d5198022
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/mach_logging.cc
@@ -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
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/mach_logging.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/mach_logging.h
new file mode 100644
index 0000000000..9ba89b4907
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/mach_logging.h
@@ -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_
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_cftyperef.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_cftyperef.h
new file mode 100644
index 0000000000..856f409509
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_cftyperef.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_
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_port.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_port.cc
new file mode 100644
index 0000000000..6f657f8340
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_port.cc
@@ -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
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_port.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_port.h
new file mode 100644
index 0000000000..dd574a44a9
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_port.h
@@ -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_
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_vm.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_vm.cc
new file mode 100644
index 0000000000..f130574411
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_vm.cc
@@ -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
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_vm.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_vm.h
new file mode 100644
index 0000000000..57dc380e30
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_mach_vm.h
@@ -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_
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_nsautorelease_pool.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_nsautorelease_pool.h
new file mode 100644
index 0000000000..58fdcbc88b
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_nsautorelease_pool.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_
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_nsautorelease_pool.mm b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_nsautorelease_pool.mm
new file mode 100644
index 0000000000..4251484b24
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_nsautorelease_pool.mm
@@ -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
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_typeref.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_typeref.h
new file mode 100644
index 0000000000..69538f56dd
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/apple/scoped_typeref.h
@@ -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_
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/pattern.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/pattern.cc
new file mode 100644
index 0000000000..cc747aab67
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/pattern.cc
@@ -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
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/pattern.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/pattern.h
new file mode 100644
index 0000000000..20c13c76dc
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/pattern.h
@@ -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_
diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/types/cxx23_to_underlying.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/types/cxx23_to_underlying.h
new file mode 100644
index 0000000000..12f1063661
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/types/cxx23_to_underlying.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_
diff --git a/thirdparty/sentry-native/external/crashpad/tools/dump_minidump_annotations.cc b/thirdparty/sentry-native/external/crashpad/tools/dump_minidump_annotations.cc
new file mode 100644
index 0000000000..1c26c1b3de
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/tools/dump_minidump_annotations.cc
@@ -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);
+}
diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/pac_helper.cc b/thirdparty/sentry-native/external/crashpad/util/linux/pac_helper.cc
new file mode 100644
index 0000000000..a9d5f04564
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/util/linux/pac_helper.cc
@@ -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
+
diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/pac_helper.h b/thirdparty/sentry-native/external/crashpad/util/linux/pac_helper.h
new file mode 100644
index 0000000000..6fcea652ab
--- /dev/null
+++ b/thirdparty/sentry-native/external/crashpad/util/linux/pac_helper.h
@@ -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_
+
diff --git a/thirdparty/sentry-native/external/libunwindstack-ndk/Demangle.cpp b/thirdparty/sentry-native/external/libunwindstack-ndk/Demangle.cpp
new file mode 100644
index 0000000000..d7ca4856af
--- /dev/null
+++ b/thirdparty/sentry-native/external/libunwindstack-ndk/Demangle.cpp
@@ -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
diff --git a/thirdparty/sentry-native/external/libunwindstack-ndk/include/unwindstack/Demangle.h b/thirdparty/sentry-native/external/libunwindstack-ndk/include/unwindstack/Demangle.h
new file mode 100644
index 0000000000..8ea51bc0b1
--- /dev/null
+++ b/thirdparty/sentry-native/external/libunwindstack-ndk/include/unwindstack/Demangle.h
@@ -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
diff --git a/thirdparty/sentry-native/external/third_party/lss/DIR_METADATA b/thirdparty/sentry-native/external/third_party/lss/DIR_METADATA
new file mode 100644
index 0000000000..eccfd35fab
--- /dev/null
+++ b/thirdparty/sentry-native/external/third_party/lss/DIR_METADATA
@@ -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"
+}
diff --git a/thirdparty/sentry-native/external/third_party/lss/LICENSE b/thirdparty/sentry-native/external/third_party/lss/LICENSE
new file mode 100644
index 0000000000..b66a6b273d
--- /dev/null
+++ b/thirdparty/sentry-native/external/third_party/lss/LICENSE
@@ -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.
diff --git a/thirdparty/sentry-native/external/third_party/lss/OWNERS b/thirdparty/sentry-native/external/third_party/lss/OWNERS
new file mode 100644
index 0000000000..29b02fa114
--- /dev/null
+++ b/thirdparty/sentry-native/external/third_party/lss/OWNERS
@@ -0,0 +1,2 @@
+mseaborn@chromium.org
+vapier@chromium.org
diff --git a/thirdparty/sentry-native/external/third_party/lss/tests/getitimer.c b/thirdparty/sentry-native/external/third_party/lss/tests/getitimer.c
new file mode 100644
index 0000000000..860538a0fb
--- /dev/null
+++ b/thirdparty/sentry-native/external/third_party/lss/tests/getitimer.c
@@ -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;
+}
diff --git a/thirdparty/sentry-native/external/third_party/lss/tests/getrandom.c b/thirdparty/sentry-native/external/third_party/lss/tests/getrandom.c
new file mode 100644
index 0000000000..0ec38b3c97
--- /dev/null
+++ b/thirdparty/sentry-native/external/third_party/lss/tests/getrandom.c
@@ -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;
+}
diff --git a/thirdparty/sentry-native/external/third_party/lss/tests/lstat.c b/thirdparty/sentry-native/external/third_party/lss/tests/lstat.c
new file mode 100644
index 0000000000..816ba9faab
--- /dev/null
+++ b/thirdparty/sentry-native/external/third_party/lss/tests/lstat.c
@@ -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;
+}
diff --git a/thirdparty/sentry-native/external/third_party/lss/tests/setitimer.c b/thirdparty/sentry-native/external/third_party/lss/tests/setitimer.c
new file mode 100644
index 0000000000..dd2ccfe5c3
--- /dev/null
+++ b/thirdparty/sentry-native/external/third_party/lss/tests/setitimer.c
@@ -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;
+}
diff --git a/thirdparty/sentry-native/external/third_party/lss/tests/sigaction.c b/thirdparty/sentry-native/external/third_party/lss/tests/sigaction.c
new file mode 100644
index 0000000000..db3658f40f
--- /dev/null
+++ b/thirdparty/sentry-native/external/third_party/lss/tests/sigaction.c
@@ -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;
+}
diff --git a/thirdparty/sentry-native/external/third_party/lss/tests/stat.c b/thirdparty/sentry-native/external/third_party/lss/tests/stat.c
new file mode 100644
index 0000000000..5ae66852dd
--- /dev/null
+++ b/thirdparty/sentry-native/external/third_party/lss/tests/stat.c
@@ -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;
+}
diff --git a/thirdparty/sentry-native/tests/unit/test_options.c b/thirdparty/sentry-native/tests/unit/test_options.c
new file mode 100644
index 0000000000..c9115a434a
--- /dev/null
+++ b/thirdparty/sentry-native/tests/unit/test_options.c
@@ -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);
+}