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