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