aboutsummaryrefslogtreecommitdiff
path: root/plat/common
diff options
context:
space:
mode:
authorAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-02-06 21:04:10 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-02-06 21:04:10 +0000
commitcabe6937f2c9d0a50e4631c0545bddd650233ae8 (patch)
tree76d9e0cabe45c1ed6d9ea87a5deb9c75c4345653 /plat/common
parentfb75a334a971078f2f231280ca87837aef5a2000 (diff)
parent1d4a3be615bde2ff311fece1ab3225cb0a0cb65d (diff)
downloadarm-trusted-firmware-b77595d8dcab28faa6492211dbea0c52e39d702b.tar.gz
Merge '5f62213e684dbea03b5a2bb732405a03ccc1a815' into master am: 5dfd96a0b3 am: 780068d4ee am: 1d4a3be615r_aml_301500702android-mainline-12.0.0_r55android-mainline-11.0.0_r9android-mainline-11.0.0_r8android-mainline-11.0.0_r7android-mainline-11.0.0_r6android-mainline-11.0.0_r5android-mainline-11.0.0_r45android-mainline-11.0.0_r44android-mainline-11.0.0_r43android-mainline-11.0.0_r42android-mainline-11.0.0_r41android-mainline-11.0.0_r40android-mainline-11.0.0_r4android-mainline-11.0.0_r39android-mainline-11.0.0_r38android-mainline-11.0.0_r37android-mainline-11.0.0_r36android-mainline-11.0.0_r35android-mainline-11.0.0_r34android-mainline-11.0.0_r33android-mainline-11.0.0_r32android-mainline-11.0.0_r31android-mainline-11.0.0_r30android-mainline-11.0.0_r3android-mainline-11.0.0_r29android-mainline-11.0.0_r28android-mainline-11.0.0_r27android-mainline-11.0.0_r26android-mainline-11.0.0_r25android-mainline-11.0.0_r24android-mainline-11.0.0_r23android-mainline-11.0.0_r22android-mainline-11.0.0_r21android-mainline-11.0.0_r20android-mainline-11.0.0_r2android-mainline-11.0.0_r19android-mainline-11.0.0_r18android-mainline-11.0.0_r17android-mainline-11.0.0_r16android-mainline-11.0.0_r15android-mainline-11.0.0_r14android-mainline-11.0.0_r13android-mainline-11.0.0_r12android-mainline-11.0.0_r10android-mainline-11.0.0_r1android-11.0.0_r48android-11.0.0_r47android-11.0.0_r46android-11.0.0_r45android-11.0.0_r44android-11.0.0_r43android-11.0.0_r42android-11.0.0_r41android-11.0.0_r40android-11.0.0_r39android-11.0.0_r38android-11.0.0_r37android-11.0.0_r36android-11.0.0_r35android-11.0.0_r34android-11.0.0_r33android-11.0.0_r32android-11.0.0_r31android-11.0.0_r30android-11.0.0_r29android-11.0.0_r28android-11.0.0_r27android-11.0.0_r26android-11.0.0_r24android-11.0.0_r23android-11.0.0_r22android-11.0.0_r21android-11.0.0_r20android-11.0.0_r19android-11.0.0_r18android-11.0.0_r16android11-qpr3-s1-releaseandroid11-qpr3-releaseandroid11-qpr2-releaseandroid11-qpr1-s2-releaseandroid11-qpr1-s1-releaseandroid11-qpr1-releaseandroid11-qpr1-d-s1-releaseandroid11-qpr1-d-releaseandroid11-qpr1-c-releaseandroid11-mainline-tethering-releaseandroid11-mainline-sparse-2021-jan-releaseandroid11-mainline-sparse-2020-dec-releaseandroid11-mainline-releaseandroid11-mainline-permission-releaseandroid11-mainline-os-statsd-releaseandroid11-mainline-networkstack-releaseandroid11-mainline-media-swcodec-releaseandroid11-mainline-media-releaseandroid11-mainline-extservices-releaseandroid11-mainline-documentsui-releaseandroid11-mainline-conscrypt-releaseandroid11-mainline-cellbroadcast-releaseandroid11-mainline-captiveportallogin-releaseandroid11-devandroid11-d2-releaseandroid11-d1-b-release
Change-Id: Ia911040759d199f8c1ec0b51abd4fa556a6b8b40
Diffstat (limited to 'plat/common')
-rw-r--r--plat/common/aarch64/crash_console_helpers.S11
-rw-r--r--plat/common/plat_psci_common.c8
-rw-r--r--plat/common/plat_spm_rd.c316
-rw-r--r--plat/common/plat_spm_sp.c93
-rw-r--r--plat/common/ubsan.c220
5 files changed, 235 insertions, 413 deletions
diff --git a/plat/common/aarch64/crash_console_helpers.S b/plat/common/aarch64/crash_console_helpers.S
index 2a48baf0a..e2950f5f7 100644
--- a/plat/common/aarch64/crash_console_helpers.S
+++ b/plat/common/aarch64/crash_console_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -125,9 +125,18 @@ putc_loop:
b.eq putc_continue
ldr x2, [x15, #CONSOLE_T_PUTC]
cbz x2, putc_continue
+ cmp w14, #'\n'
+ b.ne putc
+ tst w1, #CONSOLE_FLAG_TRANSLATE_CRLF
+ b.eq putc
mov x1, x15
+ mov w0, #'\r'
blr x2
+ ldr x2, [x15, #CONSOLE_T_PUTC]
+putc:
+ mov x1, x15
mov w0, w14
+ blr x2
putc_continue:
ldr x15, [x15] /* X15 = next struct */
b putc_loop
diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c
index 16bec7972..80ed8198b 100644
--- a/plat/common/plat_psci_common.c
+++ b/plat/common/plat_psci_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -31,6 +31,8 @@
#define PSCI_STAT_ID_EXIT_LOW_PWR 1
#define PSCI_STAT_TOTAL_IDS 2
+PMF_DECLARE_CAPTURE_TIMESTAMP(psci_svc)
+PMF_DECLARE_GET_TIMESTAMP(psci_svc)
PMF_REGISTER_SERVICE(psci_svc, PMF_PSCI_STAT_SVC_ID, PSCI_STAT_TOTAL_IDS,
PMF_STORE_ENABLE)
@@ -92,7 +94,7 @@ void plat_psci_stat_accounting_stop(
*/
u_register_t plat_psci_stat_get_residency(unsigned int lvl,
const psci_power_state_t *state_info,
- int last_cpu_idx)
+ unsigned int last_cpu_idx)
{
plat_local_state_t state;
unsigned long long pwrup_ts = 0, pwrdn_ts = 0;
@@ -103,7 +105,7 @@ u_register_t plat_psci_stat_get_residency(unsigned int lvl,
assert(last_cpu_idx <= PLATFORM_CORE_COUNT);
if (lvl == PSCI_CPU_PWR_LVL)
- assert((unsigned int)last_cpu_idx == plat_my_core_pos());
+ assert(last_cpu_idx == plat_my_core_pos());
/*
* If power down is requested, then timestamp capture will
diff --git a/plat/common/plat_spm_rd.c b/plat/common/plat_spm_rd.c
deleted file mode 100644
index ebd3e6dc6..000000000
--- a/plat/common/plat_spm_rd.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <libfdt.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <common/fdt_wrappers.h>
-#include <lib/object_pool.h>
-#include <plat/common/platform.h>
-#include <services/sp_res_desc.h>
-
-/*******************************************************************************
- * Resource pool
- ******************************************************************************/
-static struct sp_rd_sect_mem_region rd_mem_regions[PLAT_SPM_MEM_REGIONS_MAX];
-static OBJECT_POOL_ARRAY(rd_mem_regions_pool, rd_mem_regions);
-
-static struct sp_rd_sect_notification rd_notifs[PLAT_SPM_NOTIFICATIONS_MAX];
-static OBJECT_POOL_ARRAY(rd_notifs_pool, rd_notifs);
-
-static struct sp_rd_sect_service rd_services[PLAT_SPM_SERVICES_MAX];
-static OBJECT_POOL_ARRAY(rd_services_pool, rd_services);
-
-/*******************************************************************************
- * Attribute section handler
- ******************************************************************************/
-static void rd_parse_attribute(struct sp_rd_sect_attribute *attr,
- const void *fdt, int node)
-{
- int rc = 0;
-
- /* The minimum size that can be read from the DTB is 32-bit. */
- uint32_t version, sp_type, runtime_el, exec_type;
- uint32_t panic_policy, xlat_granule;
-
- rc |= fdtw_read_cells(fdt, node, "version", 1, &version);
-
- if (version != 1) {
- ERROR("Unsupported resource description version: 0x%x\n",
- version);
- panic();
- }
-
- rc |= fdtw_read_cells(fdt, node, "sp_type", 1, &sp_type);
- rc |= fdtw_read_cells(fdt, node, "pe_mpidr", 1, &attr->pe_mpidr);
- rc |= fdtw_read_cells(fdt, node, "runtime_el", 1, &runtime_el);
- rc |= fdtw_read_cells(fdt, node, "exec_type", 1, &exec_type);
- rc |= fdtw_read_cells(fdt, node, "panic_policy", 1, &panic_policy);
- rc |= fdtw_read_cells(fdt, node, "xlat_granule", 1, &xlat_granule);
- rc |= fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size);
- rc |= fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address);
- rc |= fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint);
-
- attr->version = version;
- attr->sp_type = sp_type;
- attr->runtime_el = runtime_el;
- attr->exec_type = exec_type;
- attr->panic_policy = panic_policy;
- attr->xlat_granule = xlat_granule;
-
- VERBOSE(" Attribute Section:\n");
- VERBOSE(" version: 0x%x\n", version);
- VERBOSE(" sp_type: 0x%x\n", sp_type);
- VERBOSE(" pe_mpidr: 0x%x\n", attr->pe_mpidr);
- VERBOSE(" runtime_el: 0x%x\n", runtime_el);
- VERBOSE(" exec_type: 0x%x\n", exec_type);
- VERBOSE(" panic_policy: 0x%x\n", panic_policy);
- VERBOSE(" xlat_granule: 0x%x\n", xlat_granule);
- VERBOSE(" binary_size: 0x%x\n", attr->binary_size);
- VERBOSE(" load_address: 0x%llx\n", attr->load_address);
- VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint);
-
- if (rc) {
- ERROR("Failed to read attribute node elements.\n");
- panic();
- }
-}
-
-/*******************************************************************************
- * Memory regions section handlers
- ******************************************************************************/
-static void rd_parse_memory_region(struct sp_rd_sect_mem_region *rdmem,
- const void *fdt, int node)
-{
- int rc = 0;
- char name[RD_MEM_REGION_NAME_LEN];
-
- rc |= fdtw_read_string(fdt, node, "str", (char *)&name, sizeof(name));
- rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdmem->attr);
- rc |= fdtw_read_cells(fdt, node, "base", 2, &rdmem->base);
- rc |= fdtw_read_cells(fdt, node, "size", 2, &rdmem->size);
-
- size_t len = strlcpy(rdmem->name, name, RD_MEM_REGION_NAME_LEN);
-
- if (len >= RD_MEM_REGION_NAME_LEN) {
- WARN("Memory region name truncated: '%s'\n", name);
- }
-
- VERBOSE(" Memory Region:\n");
- VERBOSE(" name: '%s'\n", rdmem->name);
- VERBOSE(" attr: 0x%x\n", rdmem->attr);
- VERBOSE(" base: 0x%llx\n", rdmem->base);
- VERBOSE(" size: 0x%llx\n", rdmem->size);
-
- if (rc) {
- ERROR("Failed to read mem_region node elements.\n");
- panic();
- }
-}
-
-static void rd_parse_memory_regions(struct sp_res_desc *rd, const void *fdt,
- int node)
-{
- int child;
- struct sp_rd_sect_mem_region *rdmem, *old_rdmem;
-
- fdt_for_each_subnode(child, fdt, node) {
- rdmem = pool_alloc(&rd_mem_regions_pool);
-
- /* Add element to the start of the list */
- old_rdmem = rd->mem_region;
- rd->mem_region = rdmem;
- rdmem->next = old_rdmem;
-
- rd_parse_memory_region(rdmem, fdt, child);
- }
-
- if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
- ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
- panic();
- }
-}
-
-/*******************************************************************************
- * Notifications section handlers
- ******************************************************************************/
-static void rd_parse_notification(struct sp_rd_sect_notification *rdnot,
- const void *fdt, int node)
-{
- int rc = 0;
-
- rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdnot->attr);
- rc |= fdtw_read_cells(fdt, node, "pe", 1, &rdnot->pe);
-
- VERBOSE(" Notification:\n");
- VERBOSE(" attr: 0x%x\n", rdnot->attr);
- VERBOSE(" pe: 0x%x\n", rdnot->pe);
-
- if (rc) {
- ERROR("Failed to read notification node elements.\n");
- panic();
- }
-}
-
-static void rd_parse_notifications(struct sp_res_desc *rd, const void *fdt, int node)
-{
- int child;
- struct sp_rd_sect_notification *rdnot, *old_rdnot;
-
- fdt_for_each_subnode(child, fdt, node) {
- rdnot = pool_alloc(&rd_notifs_pool);
-
- /* Add element to the start of the list */
- old_rdnot = rd->notification;
- rd->notification = rdnot;
- rdnot->next = old_rdnot;
-
- rd_parse_notification(rdnot, fdt, child);
- }
-
- if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
- ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, child);
- panic();
- }
-}
-
-/*******************************************************************************
- * Services section handlers
- ******************************************************************************/
-static void rd_parse_service(struct sp_rd_sect_service *rdsvc, const void *fdt,
- int node)
-{
- int rc = 0;
-
- /* The minimum size that can be read from the DTB is 32-bit. */
- uint32_t accessibility, request_type, connection_quota;
-
- rc |= fdtw_read_array(fdt, node, "uuid", 4, &rdsvc->uuid);
- rc |= fdtw_read_cells(fdt, node, "accessibility", 1, &accessibility);
- rc |= fdtw_read_cells(fdt, node, "request_type", 1, &request_type);
- rc |= fdtw_read_cells(fdt, node, "connection_quota", 1, &connection_quota);
- rc |= fdtw_read_cells(fdt, node, "sec_mem_size", 1, &rdsvc->secure_mem_size);
- rc |= fdtw_read_cells(fdt, node, "interrupt_num", 1, &rdsvc->interrupt_num);
-
- rdsvc->accessibility = accessibility;
- rdsvc->request_type = request_type;
- rdsvc->connection_quota = connection_quota;
-
- VERBOSE(" Service:\n");
- VERBOSE(" uuid: 0x%08x 0x%08x 0x%08x 0x%08x\n", rdsvc->uuid[0],
- rdsvc->uuid[1], rdsvc->uuid[2], rdsvc->uuid[3]);
- VERBOSE(" accessibility: 0x%x\n", accessibility);
- VERBOSE(" request_type: 0x%x\n", request_type);
- VERBOSE(" connection_quota: 0x%x\n", connection_quota);
- VERBOSE(" secure_memory_size: 0x%x\n", rdsvc->secure_mem_size);
- VERBOSE(" interrupt_num: 0x%x\n", rdsvc->interrupt_num);
-
- if (rc) {
- ERROR("Failed to read attribute node elements.\n");
- panic();
- }
-}
-
-static void rd_parse_services(struct sp_res_desc *rd, const void *fdt, int node)
-{
- int child;
- struct sp_rd_sect_service *rdsvc, *old_rdsvc;
-
- fdt_for_each_subnode(child, fdt, node) {
- rdsvc = pool_alloc(&rd_services_pool);
-
- /* Add element to the start of the list */
- old_rdsvc = rd->service;
- rd->service = rdsvc;
- rdsvc->next = old_rdsvc;
-
- rd_parse_service(rdsvc, fdt, child);
- }
-
- if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
- ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
- panic();
- }
-}
-
-/*******************************************************************************
- * Root node handler
- ******************************************************************************/
-static void rd_parse_root(struct sp_res_desc *rd, const void *fdt, int root)
-{
- int node;
- char *str;
-
- str = "attribute";
- node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
- if (node < 0) {
- ERROR("Root node doesn't contain subnode '%s'\n", str);
- panic();
- } else {
- rd_parse_attribute(&rd->attribute, fdt, node);
- }
-
- str = "memory_regions";
- node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
- if (node < 0) {
- ERROR("Root node doesn't contain subnode '%s'\n", str);
- panic();
- } else {
- rd_parse_memory_regions(rd, fdt, node);
- }
-
- str = "notifications";
- node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
- if (node < 0) {
- WARN("Root node doesn't contain subnode '%s'\n", str);
- } else {
- rd_parse_notifications(rd, fdt, node);
- }
-
- str = "services";
- node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
- if (node < 0) {
- WARN("Root node doesn't contain subnode '%s'\n", str);
- } else {
- rd_parse_services(rd, fdt, node);
- }
-}
-
-/*******************************************************************************
- * Platform handler to load resource descriptor blobs into the active Secure
- * Partition context.
- ******************************************************************************/
-int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size)
-{
- int rc;
- int root_node;
-
- assert(rd != NULL);
- assert(ptr != NULL);
-
- INFO("Reading RD blob at address %p\n", ptr);
-
- rc = fdt_check_header(ptr);
- if (rc != 0) {
- ERROR("Wrong format for resource descriptor blob (%d).\n", rc);
- return -1;
- }
-
- root_node = fdt_node_offset_by_compatible(ptr, -1, "arm,sp_rd");
- if (root_node < 0) {
- ERROR("Unrecognized resource descriptor blob (%d)\n", rc);
- return -1;
- }
-
- rd_parse_root(rd, ptr, root_node);
-
- return 0;
-}
diff --git a/plat/common/plat_spm_sp.c b/plat/common/plat_spm_sp.c
deleted file mode 100644
index bc3d6a015..000000000
--- a/plat/common/plat_spm_sp.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <plat/common/platform.h>
-#include <tools_share/sptool.h>
-
-static unsigned int sp_next;
-
-/*******************************************************************************
- * Platform handler get the address of a Secure Partition and its resource
- * description blob. It iterates through all SPs detected by the platform. If
- * there is information for another SP, it returns 0. If there are no more SPs,
- * it returns -1.
- ******************************************************************************/
-int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
- void **rd_base, size_t *rd_size)
-{
- assert((sp_base != NULL) && (sp_size != NULL));
- assert((rd_base != NULL) && (rd_base != NULL));
-
- const uint64_t *pkg_base = (uint64_t *)PLAT_SP_PACKAGE_BASE;
-
- struct sp_pkg_header *pkg_header = (struct sp_pkg_header *)pkg_base;
-
- if (sp_next == 0) {
- if (pkg_header->version != 0x1) {
- ERROR("SP package has an unsupported version 0x%llx\n",
- pkg_header->version);
- panic();
- }
- }
-
- if (sp_next >= pkg_header->number_of_sp) {
- /* No more partitions in the package */
- return -1;
- }
-
- const struct sp_pkg_entry *entry_list =
- (const struct sp_pkg_entry *)((uintptr_t)pkg_base
- + sizeof(struct sp_pkg_header));
-
- const struct sp_pkg_entry *entry = &(entry_list[sp_next]);
-
- uint64_t sp_offset = entry->sp_offset;
- uint64_t rd_offset = entry->rd_offset;
-
- uintptr_t pkg_sp_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + sp_offset);
- uintptr_t pkg_rd_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + rd_offset);
-
- uint64_t pkg_sp_size = entry->sp_size;
- uint64_t pkg_rd_size = entry->rd_size;
-
- uintptr_t pkg_end = (uintptr_t)PLAT_SP_PACKAGE_BASE
- + (uintptr_t)PLAT_SP_PACKAGE_SIZE - 1U;
-
- /*
- * Check for overflows. The package header isn't trusted, so assert()
- * can't be used here.
- */
-
- uintptr_t pkg_sp_end = pkg_sp_base + pkg_sp_size - 1U;
- uintptr_t pkg_rd_end = pkg_rd_base + pkg_rd_size - 1U;
-
- if ((pkg_sp_end > pkg_end) || (pkg_sp_end < pkg_sp_base)) {
- ERROR("Invalid Secure Partition size (0x%llx)\n", pkg_sp_size);
- panic();
- }
-
- if ((pkg_rd_end > pkg_end) || (pkg_rd_end < pkg_rd_base)) {
- ERROR("Invalid Resource Description blob size (0x%llx)\n",
- pkg_rd_size);
- panic();
- }
-
- /* Return location of the binaries. */
-
- *sp_base = (void *)pkg_sp_base;
- *sp_size = pkg_sp_size;
- *rd_base = (void *)pkg_rd_base;
- *rd_size = pkg_rd_size;
-
- sp_next++;
-
- return 0;
-}
diff --git a/plat/common/ubsan.c b/plat/common/ubsan.c
new file mode 100644
index 000000000..45b0f7cce
--- /dev/null
+++ b/plat/common/ubsan.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2016, Linaro Limited
+ * Copyright (c) 2019, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <arch_helpers.h>
+#include <context.h>
+#include <common/debug.h>
+#include <plat/common/platform.h>
+
+struct source_location {
+ const char *file_name;
+ uint32_t line;
+ uint32_t column;
+};
+
+struct type_descriptor {
+ uint16_t type_kind;
+ uint16_t type_info;
+ char type_name[1];
+};
+
+struct type_mismatch_data {
+ struct source_location loc;
+ struct type_descriptor *type;
+ unsigned long alignment;
+ unsigned char type_check_kind;
+};
+
+struct overflow_data {
+ struct source_location loc;
+ struct type_descriptor *type;
+};
+
+struct shift_out_of_bounds_data {
+ struct source_location loc;
+ struct type_descriptor *lhs_type;
+ struct type_descriptor *rhs_type;
+};
+
+struct out_of_bounds_data {
+ struct source_location loc;
+ struct type_descriptor *array_type;
+ struct type_descriptor *index_type;
+};
+
+struct unreachable_data {
+ struct source_location loc;
+};
+
+struct vla_bound_data {
+ struct source_location loc;
+ struct type_descriptor *type;
+};
+
+struct invalid_value_data {
+ struct source_location loc;
+ struct type_descriptor *type;
+};
+
+struct nonnull_arg_data {
+ struct source_location loc;
+};
+
+/*
+ * When compiling with -fsanitize=undefined the compiler expects functions
+ * with the following signatures. The functions are never called directly,
+ * only when undefined behavior is detected in instrumented code.
+ */
+void __ubsan_handle_type_mismatch_abort(struct type_mismatch_data *data,
+ unsigned long ptr);
+void __ubsan_handle_type_mismatch_v1_abort(struct type_mismatch_data *data,
+ unsigned long ptr);
+void __ubsan_handle_add_overflow_abort(struct overflow_data *data,
+ unsigned long lhs, unsigned long rhs);
+void __ubsan_handle_sub_overflow_abort(struct overflow_data *data,
+ unsigned long lhs, unsigned long rhs);
+void __ubsan_handle_mul_overflow_abort(struct overflow_data *data,
+ unsigned long lhs, unsigned long rhs);
+void __ubsan_handle_negate_overflow_abort(struct overflow_data *data,
+ unsigned long old_val);
+void __ubsan_handle_pointer_overflow_abort(struct overflow_data *data,
+ unsigned long old_val);
+void __ubsan_handle_divrem_overflow_abort(struct overflow_data *data,
+ unsigned long lhs, unsigned long rhs);
+void __ubsan_handle_shift_out_of_bounds_abort(struct shift_out_of_bounds_data *data,
+ unsigned long lhs, unsigned long rhs);
+void __ubsan_handle_out_of_bounds_abort(struct out_of_bounds_data *data,
+ unsigned long idx);
+void __ubsan_handle_unreachable_abort(struct unreachable_data *data);
+void __ubsan_handle_missing_return_abort(struct unreachable_data *data);
+void __ubsan_handle_vla_bound_not_positive_abort(struct vla_bound_data *data,
+ unsigned long bound);
+void __ubsan_handle_load_invalid_value_abort(struct invalid_value_data *data,
+ unsigned long val);
+void __ubsan_handle_nonnull_arg_abort(struct nonnull_arg_data *data
+#if __GCC_VERSION < 60000
+ , size_t arg_no
+#endif
+ );
+
+static void print_loc(const char *func, struct source_location *loc)
+{
+ ERROR("Undefined behavior at %s:%d col %d (%s)",
+ loc->file_name, loc->line, loc->column, func);
+}
+
+
+void __ubsan_handle_type_mismatch_abort(struct type_mismatch_data *data,
+ unsigned long ptr __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_type_mismatch_v1_abort(struct type_mismatch_data *data,
+ unsigned long ptr __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_add_overflow_abort(struct overflow_data *data,
+ unsigned long lhs __unused,
+ unsigned long rhs __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_sub_overflow_abort(struct overflow_data *data,
+ unsigned long lhs __unused,
+ unsigned long rhs __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_mul_overflow_abort(struct overflow_data *data,
+ unsigned long lhs __unused,
+ unsigned long rhs __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_negate_overflow_abort(struct overflow_data *data,
+ unsigned long old_val __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_pointer_overflow_abort(struct overflow_data *data,
+ unsigned long old_val __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_divrem_overflow_abort(struct overflow_data *data,
+ unsigned long lhs __unused,
+ unsigned long rhs __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_shift_out_of_bounds_abort(struct shift_out_of_bounds_data *data,
+ unsigned long lhs __unused,
+ unsigned long rhs __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_out_of_bounds_abort(struct out_of_bounds_data *data,
+ unsigned long idx __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_unreachable_abort(struct unreachable_data *data)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_missing_return_abort(struct unreachable_data *data)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_vla_bound_not_positive_abort(struct vla_bound_data *data,
+ unsigned long bound __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_load_invalid_value_abort(struct invalid_value_data *data,
+ unsigned long val __unused)
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}
+
+void __ubsan_handle_nonnull_arg_abort(struct nonnull_arg_data *data
+#if __GCC_VERSION < 60000
+ , size_t arg_no __unused
+#endif
+ )
+{
+ print_loc(__func__, &data->loc);
+ plat_panic_handler();
+}