1c96bced4SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2c96bced4SJerome Forissier /* 3c96bced4SJerome Forissier * Copyright (c) 2019 Linaro limited 4c96bced4SJerome Forissier */ 5c96bced4SJerome Forissier 6c96bced4SJerome Forissier #include <ctype.h> 7c96bced4SJerome Forissier #include <dlfcn.h> 8c96bced4SJerome Forissier #include <pta_system.h> 9c96bced4SJerome Forissier #include <stdlib.h> 10c96bced4SJerome Forissier #include <string.h> 11c96bced4SJerome Forissier #include <tee_api.h> 12c96bced4SJerome Forissier #include <tee_internal_api_extensions.h> 13*dd655cb9SJerome Forissier #include <user_ta_header.h> 14c96bced4SJerome Forissier 15c96bced4SJerome Forissier static TEE_TASessionHandle sess = TEE_HANDLE_NULL; 16c96bced4SJerome Forissier static size_t hcount; 17c96bced4SJerome Forissier 18c96bced4SJerome Forissier static TEE_Result invoke_system_pta(uint32_t cmd_id, uint32_t param_types, 19c96bced4SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 20c96bced4SJerome Forissier { 21c96bced4SJerome Forissier const TEE_UUID core_uuid = PTA_SYSTEM_UUID; 22c96bced4SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 23c96bced4SJerome Forissier 24c96bced4SJerome Forissier if (sess == TEE_HANDLE_NULL) { 25542ae207SCedric Auger res = TEE_OpenTASession(&core_uuid, TEE_TIMEOUT_INFINITE, 26542ae207SCedric Auger 0, NULL, &sess, NULL); 27c96bced4SJerome Forissier if (res) 28c96bced4SJerome Forissier return res; 29c96bced4SJerome Forissier } 30542ae207SCedric Auger return TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, 31542ae207SCedric Auger cmd_id, param_types, params, NULL); 32c96bced4SJerome Forissier } 33c96bced4SJerome Forissier 34c96bced4SJerome Forissier struct dl_handle { 35c96bced4SJerome Forissier TEE_UUID uuid; 36c96bced4SJerome Forissier }; 37c96bced4SJerome Forissier 38c96bced4SJerome Forissier void *dlopen(const char *filename, int flags) 39c96bced4SJerome Forissier { 40c96bced4SJerome Forissier TEE_Param params[TEE_NUM_PARAMS] = { }; 41c96bced4SJerome Forissier struct dl_handle *h = NULL; 42c96bced4SJerome Forissier uint32_t param_types = 0; 43c96bced4SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 44c96bced4SJerome Forissier TEE_UUID uuid = { }; 45c96bced4SJerome Forissier 46c96bced4SJerome Forissier h = malloc(sizeof(*h)); 47c96bced4SJerome Forissier if (!h) 48c96bced4SJerome Forissier return NULL; 49c96bced4SJerome Forissier 50c96bced4SJerome Forissier if (filename) { 51c96bced4SJerome Forissier res = tee_uuid_from_str(&uuid, filename); 52c96bced4SJerome Forissier if (res) 53c96bced4SJerome Forissier goto err; 54c96bced4SJerome Forissier 55c96bced4SJerome Forissier param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 56c96bced4SJerome Forissier TEE_PARAM_TYPE_VALUE_INPUT, 57c96bced4SJerome Forissier TEE_PARAM_TYPE_NONE, 58c96bced4SJerome Forissier TEE_PARAM_TYPE_NONE); 59c96bced4SJerome Forissier 60c96bced4SJerome Forissier params[0].memref.buffer = (void *)&uuid; 61c96bced4SJerome Forissier params[0].memref.size = sizeof(uuid); 62c96bced4SJerome Forissier params[1].value.a = flags; 63c96bced4SJerome Forissier 64c96bced4SJerome Forissier res = invoke_system_pta(PTA_SYSTEM_DLOPEN, param_types, params); 65c96bced4SJerome Forissier if (res) 66c96bced4SJerome Forissier goto err; 67*dd655cb9SJerome Forissier 68*dd655cb9SJerome Forissier __utee_call_elf_init_fn(); 69c96bced4SJerome Forissier } 70c96bced4SJerome Forissier 71c96bced4SJerome Forissier hcount++; 72c96bced4SJerome Forissier h->uuid = uuid; 73c96bced4SJerome Forissier return (void *)h; 74c96bced4SJerome Forissier err: 75c96bced4SJerome Forissier free(h); 76c96bced4SJerome Forissier return NULL; 77c96bced4SJerome Forissier } 78c96bced4SJerome Forissier 79c96bced4SJerome Forissier int dlclose(void *handle) 80c96bced4SJerome Forissier { 81c96bced4SJerome Forissier free(handle); 82c96bced4SJerome Forissier hcount--; 83c96bced4SJerome Forissier if (!hcount && sess != TEE_HANDLE_NULL) { 84c96bced4SJerome Forissier TEE_CloseTASession(sess); 85c96bced4SJerome Forissier sess = TEE_HANDLE_NULL; 86c96bced4SJerome Forissier } 87c96bced4SJerome Forissier return 0; 88c96bced4SJerome Forissier } 89c96bced4SJerome Forissier 90c96bced4SJerome Forissier void *dlsym(void *handle, const char *symbol) 91c96bced4SJerome Forissier { 92c96bced4SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 93c96bced4SJerome Forissier TEE_Param params[TEE_NUM_PARAMS] = { }; 94c96bced4SJerome Forissier struct dl_handle *h = handle; 95c96bced4SJerome Forissier uint32_t param_types = 0; 96c96bced4SJerome Forissier void *ptr = NULL; 97c96bced4SJerome Forissier 98c96bced4SJerome Forissier if (!handle || !symbol) 99c96bced4SJerome Forissier return NULL; 100c96bced4SJerome Forissier 101c96bced4SJerome Forissier param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 102c96bced4SJerome Forissier TEE_PARAM_TYPE_MEMREF_INPUT, 103c96bced4SJerome Forissier TEE_PARAM_TYPE_VALUE_OUTPUT, 104c96bced4SJerome Forissier TEE_PARAM_TYPE_NONE); 105c96bced4SJerome Forissier 106c96bced4SJerome Forissier params[0].memref.buffer = &h->uuid; 107c96bced4SJerome Forissier params[0].memref.size = sizeof(h->uuid); 108c96bced4SJerome Forissier params[1].memref.buffer = (void *)symbol; 109c96bced4SJerome Forissier params[1].memref.size = strlen(symbol) + 1; 110c96bced4SJerome Forissier 111c96bced4SJerome Forissier res = invoke_system_pta(PTA_SYSTEM_DLSYM, param_types, params); 112c96bced4SJerome Forissier if (!res) 113c96bced4SJerome Forissier ptr = (void *)(vaddr_t)reg_pair_to_64(params[2].value.a, 114c96bced4SJerome Forissier params[2].value.b); 115c96bced4SJerome Forissier 116c96bced4SJerome Forissier return ptr; 117c96bced4SJerome Forissier } 118c96bced4SJerome Forissier 119