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