14cafd8a3SAleksandr Iashchenko // SPDX-License-Identifier: BSD-2-Clause
24cafd8a3SAleksandr Iashchenko /*
34cafd8a3SAleksandr Iashchenko * Copyright (c) 2026, Linutronix GmbH
44cafd8a3SAleksandr Iashchenko */
54cafd8a3SAleksandr Iashchenko
64cafd8a3SAleksandr Iashchenko #include <compiler.h>
74cafd8a3SAleksandr Iashchenko #include <ldelf.h>
84cafd8a3SAleksandr Iashchenko
94cafd8a3SAleksandr Iashchenko #include "asan.h"
104cafd8a3SAleksandr Iashchenko #include "sys.h"
114cafd8a3SAleksandr Iashchenko
init_run_constructors(void)124cafd8a3SAleksandr Iashchenko static void init_run_constructors(void)
134cafd8a3SAleksandr Iashchenko {
144cafd8a3SAleksandr Iashchenko const vaddr_t *ctor = NULL;
154cafd8a3SAleksandr Iashchenko
164cafd8a3SAleksandr Iashchenko for (ctor = &__init_array_start; ctor < &__init_array_end; ctor++)
174cafd8a3SAleksandr Iashchenko ((void (*)(void))(*ctor))();
184cafd8a3SAleksandr Iashchenko }
194cafd8a3SAleksandr Iashchenko
asan_ldelf_map_stack(size_t size)204cafd8a3SAleksandr Iashchenko static int asan_ldelf_map_stack(size_t size)
214cafd8a3SAleksandr Iashchenko {
224cafd8a3SAleksandr Iashchenko vaddr_t stack_top = (vaddr_t)&stack_top;
234cafd8a3SAleksandr Iashchenko vaddr_t stack_base = 0;
244cafd8a3SAleksandr Iashchenko
254cafd8a3SAleksandr Iashchenko size = ROUNDUP(size, SMALL_PAGE_SIZE);
264cafd8a3SAleksandr Iashchenko stack_top = ROUNDUP(stack_top, SMALL_PAGE_SIZE);
274cafd8a3SAleksandr Iashchenko stack_base = stack_top - size;
284cafd8a3SAleksandr Iashchenko
29*b8a0c52cSAleksandr Iashchenko return asan_user_map_shadow((void *)stack_base, (void *)stack_top,
30*b8a0c52cSAleksandr Iashchenko ASAN_REG_STACK);
314cafd8a3SAleksandr Iashchenko }
324cafd8a3SAleksandr Iashchenko
asan_init_ldelf(void)334cafd8a3SAleksandr Iashchenko TEE_Result asan_init_ldelf(void)
344cafd8a3SAleksandr Iashchenko {
354cafd8a3SAleksandr Iashchenko vaddr_t req = (vaddr_t)GET_ASAN_INFO();
364cafd8a3SAleksandr Iashchenko TEE_Result rc = TEE_SUCCESS;
374cafd8a3SAleksandr Iashchenko vaddr_t tmp = req;
384cafd8a3SAleksandr Iashchenko
394cafd8a3SAleksandr Iashchenko /* Map global ASan info */
404cafd8a3SAleksandr Iashchenko rc = sys_map_zi(sizeof(struct asan_global_info), 0, &tmp, 0, 0);
414cafd8a3SAleksandr Iashchenko if (rc == TEE_SUCCESS && req == tmp) {
424cafd8a3SAleksandr Iashchenko /* Map shadow stack for ldelf */
434cafd8a3SAleksandr Iashchenko rc = asan_ldelf_map_stack(LDELF_STACK_SIZE);
444cafd8a3SAleksandr Iashchenko if (rc) {
454cafd8a3SAleksandr Iashchenko EMSG("failed to map ldelf shadow stack");
464cafd8a3SAleksandr Iashchenko panic();
474cafd8a3SAleksandr Iashchenko }
484cafd8a3SAleksandr Iashchenko /* Map shadow memory for ldelf binary sections */
494cafd8a3SAleksandr Iashchenko rc = asan_user_map_shadow((void *)__text_start,
504cafd8a3SAleksandr Iashchenko (void *)ROUNDUP((vaddr_t)__end,
51*b8a0c52cSAleksandr Iashchenko SMALL_PAGE_SIZE),
52*b8a0c52cSAleksandr Iashchenko ASAN_REG_ELF);
534cafd8a3SAleksandr Iashchenko if (rc) {
544cafd8a3SAleksandr Iashchenko EMSG("failed to map ldelf shadow elf sections");
554cafd8a3SAleksandr Iashchenko panic();
564cafd8a3SAleksandr Iashchenko }
574cafd8a3SAleksandr Iashchenko /* Register global ASan constructors */
584cafd8a3SAleksandr Iashchenko init_run_constructors();
594cafd8a3SAleksandr Iashchenko } else {
604cafd8a3SAleksandr Iashchenko rc = TEE_ERROR_GENERIC;
614cafd8a3SAleksandr Iashchenko }
624cafd8a3SAleksandr Iashchenko
634cafd8a3SAleksandr Iashchenko return rc;
644cafd8a3SAleksandr Iashchenko }
65