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