1*418b791dSBob Badour /*
2*418b791dSBob Badour * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3*418b791dSBob Badour *
4*418b791dSBob Badour * Redistribution and use in source and binary forms, with or without
5*418b791dSBob Badour * modification, are permitted provided that the following conditions are
6*418b791dSBob Badour * met:
7*418b791dSBob Badour * * Redistributions of source code must retain the above copyright
8*418b791dSBob Badour * notice, this list of conditions and the following disclaimer.
9*418b791dSBob Badour * * Redistributions in binary form must reproduce the above
10*418b791dSBob Badour * copyright notice, this list of conditions and the following
11*418b791dSBob Badour * disclaimer in the documentation and/or other materials provided
12*418b791dSBob Badour * with the distribution.
13*418b791dSBob Badour * * Neither the name of The Linux Foundation nor the names of its
14*418b791dSBob Badour * contributors may be used to endorse or promote products derived
15*418b791dSBob Badour * from this software without specific prior written permission.
16*418b791dSBob Badour *
17*418b791dSBob Badour * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18*418b791dSBob Badour * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19*418b791dSBob Badour * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20*418b791dSBob Badour * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21*418b791dSBob Badour * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*418b791dSBob Badour * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*418b791dSBob Badour * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24*418b791dSBob Badour * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25*418b791dSBob Badour * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26*418b791dSBob Badour * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27*418b791dSBob Badour * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*418b791dSBob Badour */
29*418b791dSBob Badour #ifndef FARF_ERROR
30*418b791dSBob Badour #define FARF_ERROR 1
31*418b791dSBob Badour #endif
32*418b791dSBob Badour
33*418b791dSBob Badour #include <assert.h>
34*418b791dSBob Badour #include "verify.h"
35*418b791dSBob Badour #include "HAP_farf.h"
36*418b791dSBob Badour #include "HAP_pls.h"
37*418b791dSBob Badour #include "mutex.h"
38*418b791dSBob Badour #include "mod_table.h"
39*418b791dSBob Badour #include "platform_libs.h"
40*418b791dSBob Badour #include "remote64.h"
41*418b791dSBob Badour #include "uthash.h"
42*418b791dSBob Badour #include "AEEstd.h"
43*418b791dSBob Badour #include "AEEStdErr.h"
44*418b791dSBob Badour #include "sbuf_parser.h"
45*418b791dSBob Badour
46*418b791dSBob Badour #include <dlfcn.h>
47*418b791dSBob Badour
48*418b791dSBob Badour #define DLOPEN dlopen
49*418b791dSBob Badour #define DLCLOSE dlclose
50*418b791dSBob Badour #define DLSYM dlsym
51*418b791dSBob Badour #define DLERROR dlerror
52*418b791dSBob Badour
53*418b791dSBob Badour /**
54*418b791dSBob Badour * structure for the mod table
55*418b791dSBob Badour *
56*418b791dSBob Badour * you need to define a rw_mutex type and its read/write lock/unlock api's
57*418b791dSBob Badour * which are under the RW_MUTEX namespace.
58*418b791dSBob Badour *
59*418b791dSBob Badour * this library defines 2 functions for opening modules, open_static and
60*418b791dSBob Badour * open_dynamic. Both return a handle that should be closed via close.
61*418b791dSBob Badour *
62*418b791dSBob Badour * you can also register a const handle, an invoke function for a known handle
63*418b791dSBob Badour * value. since handle keys are allocated, you should pick handle values that are
64*418b791dSBob Badour * not going to be returned by malloc (0, or odd).
65*418b791dSBob Badour */
66*418b791dSBob Badour struct static_mod_table {
67*418b791dSBob Badour RW_MUTEX_T mut;
68*418b791dSBob Badour struct static_mod* staticModOverrides;
69*418b791dSBob Badour struct static_mod* staticMods;
70*418b791dSBob Badour struct const_mod* constMods;
71*418b791dSBob Badour boolean bInit;
72*418b791dSBob Badour };
73*418b791dSBob Badour
74*418b791dSBob Badour struct open_mod_table {
75*418b791dSBob Badour RW_MUTEX_T mut;
76*418b791dSBob Badour struct open_mod* openMods;
77*418b791dSBob Badour struct static_mod_table* smt;
78*418b791dSBob Badour };
79*418b791dSBob Badour
80*418b791dSBob Badour typedef int (*invoke_fn)(uint32, remote_arg*);
81*418b791dSBob Badour typedef int (*handle_invoke_fn)(remote_handle64, uint32, remote_arg*);
82*418b791dSBob Badour struct static_mod {
83*418b791dSBob Badour invoke_fn invoke;
84*418b791dSBob Badour handle_invoke_fn handle_invoke;
85*418b791dSBob Badour UT_hash_handle hh;
86*418b791dSBob Badour char uri[1];
87*418b791dSBob Badour };
88*418b791dSBob Badour
89*418b791dSBob Badour struct const_mod {
90*418b791dSBob Badour invoke_fn invoke;
91*418b791dSBob Badour handle_invoke_fn handle_invoke;
92*418b791dSBob Badour uint32 key;
93*418b791dSBob Badour remote_handle64 h64;
94*418b791dSBob Badour UT_hash_handle hh;
95*418b791dSBob Badour char uri[1];
96*418b791dSBob Badour };
97*418b791dSBob Badour
98*418b791dSBob Badour struct parsed_uri {
99*418b791dSBob Badour const char *file;
100*418b791dSBob Badour int filelen;
101*418b791dSBob Badour const char *sym;
102*418b791dSBob Badour int symlen;
103*418b791dSBob Badour const char *ver;
104*418b791dSBob Badour int verlen;
105*418b791dSBob Badour };
106*418b791dSBob Badour
107*418b791dSBob Badour struct open_mod {
108*418b791dSBob Badour void* dlhandle;
109*418b791dSBob Badour invoke_fn invoke;
110*418b791dSBob Badour handle_invoke_fn handle_invoke;
111*418b791dSBob Badour uint64 key;
112*418b791dSBob Badour UT_hash_handle hh;
113*418b791dSBob Badour remote_handle64 h64;
114*418b791dSBob Badour int refs;
115*418b791dSBob Badour struct parsed_uri vals;
116*418b791dSBob Badour char uri[1];
117*418b791dSBob Badour };
118*418b791dSBob Badour
static_mod_table_ctor(struct static_mod_table * me)119*418b791dSBob Badour static int static_mod_table_ctor(struct static_mod_table* me) {
120*418b791dSBob Badour if(me->bInit == 0) {
121*418b791dSBob Badour RW_MUTEX_CTOR(me->mut);
122*418b791dSBob Badour me->staticMods = 0;
123*418b791dSBob Badour me->staticModOverrides = 0;
124*418b791dSBob Badour me->bInit = 1;
125*418b791dSBob Badour }
126*418b791dSBob Badour return 0;
127*418b791dSBob Badour }
128*418b791dSBob Badour
static_mod_table_dtor_imp(struct static_mod_table * me)129*418b791dSBob Badour static void static_mod_table_dtor_imp(struct static_mod_table* me) {
130*418b791dSBob Badour struct static_mod *sm, *stmp;
131*418b791dSBob Badour struct const_mod *dm, *ftmp;
132*418b791dSBob Badour if(me->bInit != 0) {
133*418b791dSBob Badour if( me->staticMods || me->constMods || me->staticModOverrides) {
134*418b791dSBob Badour RW_MUTEX_LOCK_WRITE(me->mut);
135*418b791dSBob Badour HASH_ITER(hh, me->staticMods, sm, stmp) {
136*418b791dSBob Badour if(me->staticMods) {
137*418b791dSBob Badour HASH_DEL(me->staticMods,sm);
138*418b791dSBob Badour }
139*418b791dSBob Badour free(sm);
140*418b791dSBob Badour sm = NULL;
141*418b791dSBob Badour }
142*418b791dSBob Badour HASH_ITER(hh, me->staticModOverrides, sm, stmp) {
143*418b791dSBob Badour if(me->staticModOverrides) {
144*418b791dSBob Badour HASH_DEL(me->staticModOverrides,sm);
145*418b791dSBob Badour }
146*418b791dSBob Badour free(sm);
147*418b791dSBob Badour sm = NULL;
148*418b791dSBob Badour }
149*418b791dSBob Badour HASH_ITER(hh, me->constMods, dm, ftmp) {
150*418b791dSBob Badour if(me->constMods) {
151*418b791dSBob Badour HASH_DEL(me->constMods,dm);
152*418b791dSBob Badour }
153*418b791dSBob Badour free(dm);
154*418b791dSBob Badour dm = NULL;
155*418b791dSBob Badour }
156*418b791dSBob Badour RW_MUTEX_UNLOCK_WRITE(me->mut);
157*418b791dSBob Badour }
158*418b791dSBob Badour RW_MUTEX_DTOR(me->mut);
159*418b791dSBob Badour me->staticMods = 0;
160*418b791dSBob Badour me->staticModOverrides = 0;
161*418b791dSBob Badour me->bInit = 0;
162*418b791dSBob Badour }
163*418b791dSBob Badour }
164*418b791dSBob Badour
open_mod_table_ctor_imp(void * ctx,void * data)165*418b791dSBob Badour static int open_mod_table_ctor_imp(void* ctx, void* data) {
166*418b791dSBob Badour struct open_mod_table* me = (struct open_mod_table*)data;
167*418b791dSBob Badour RW_MUTEX_CTOR(me->mut);
168*418b791dSBob Badour me->openMods = 0;
169*418b791dSBob Badour me->smt = (struct static_mod_table*) ctx;
170*418b791dSBob Badour return 0;
171*418b791dSBob Badour }
172*418b791dSBob Badour
173*418b791dSBob Badour static int open_mod_handle_close(struct open_mod *mod, remote_handle64 h);
174*418b791dSBob Badour
open_mod_table_dtor_imp(void * data)175*418b791dSBob Badour static void open_mod_table_dtor_imp(void* data) {
176*418b791dSBob Badour struct open_mod_table* me = (struct open_mod_table*)data;
177*418b791dSBob Badour struct open_mod *dm, *ftmp;
178*418b791dSBob Badour if( me->openMods) {
179*418b791dSBob Badour RW_MUTEX_LOCK_WRITE(me->mut);
180*418b791dSBob Badour HASH_ITER(hh, me->openMods, dm, ftmp) {
181*418b791dSBob Badour if(me->openMods) {
182*418b791dSBob Badour HASH_DEL(me->openMods,dm);
183*418b791dSBob Badour }
184*418b791dSBob Badour if(dm->h64) {
185*418b791dSBob Badour (void)open_mod_handle_close(dm, dm->h64);
186*418b791dSBob Badour }
187*418b791dSBob Badour if(dm->dlhandle) {
188*418b791dSBob Badour DLCLOSE(dm->dlhandle);
189*418b791dSBob Badour }
190*418b791dSBob Badour free(dm);
191*418b791dSBob Badour }
192*418b791dSBob Badour RW_MUTEX_UNLOCK_WRITE(me->mut);
193*418b791dSBob Badour }
194*418b791dSBob Badour RW_MUTEX_DTOR(me->mut);
195*418b791dSBob Badour me->openMods = 0;
196*418b791dSBob Badour }
197*418b791dSBob Badour static int open_mod_table_open_from_static(struct open_mod_table* me,
198*418b791dSBob Badour struct static_mod** tbl,
199*418b791dSBob Badour const char* uri,
200*418b791dSBob Badour remote_handle* handle);
201*418b791dSBob Badour
open_mod_table_open_static_override(struct open_mod_table * me,const char * uri,remote_handle * handle)202*418b791dSBob Badour static int open_mod_table_open_static_override(struct open_mod_table* me, const char* uri, remote_handle* handle) {
203*418b791dSBob Badour FARF(HIGH, "open_mod_table_open_static_override");
204*418b791dSBob Badour return open_mod_table_open_from_static(me, &me->smt->staticModOverrides, uri, handle);
205*418b791dSBob Badour }
206*418b791dSBob Badour
207*418b791dSBob Badour
open_mod_table_open_static(struct open_mod_table * me,const char * uri,remote_handle * handle)208*418b791dSBob Badour static int open_mod_table_open_static(struct open_mod_table* me, const char* uri, remote_handle* handle) {
209*418b791dSBob Badour FARF(HIGH, "open_mod_table_open_static");
210*418b791dSBob Badour return open_mod_table_open_from_static(me, &me->smt->staticMods, uri, handle);
211*418b791dSBob Badour }
212*418b791dSBob Badour
static_mod_add(struct static_mod_table * me,struct static_mod ** tbl,const char * uri,int (* invoke)(uint32 sc,remote_arg * pra),int (* handle_invoke)(remote_handle64,uint32 sc,remote_arg * pra))213*418b791dSBob Badour static int static_mod_add(struct static_mod_table* me, struct static_mod** tbl, const char* uri,
214*418b791dSBob Badour int(*invoke)(uint32 sc, remote_arg* pra),
215*418b791dSBob Badour int(*handle_invoke)(remote_handle64, uint32 sc, remote_arg* pra)) {
216*418b791dSBob Badour int nErr = AEE_SUCCESS;
217*418b791dSBob Badour struct static_mod *sm = 0;
218*418b791dSBob Badour int len = std_strlen(uri) + 1;
219*418b791dSBob Badour VERIFYC(NULL != (sm = ((struct static_mod*)calloc(1, sizeof(struct static_mod) + len))), AEE_ENOMEMORY);
220*418b791dSBob Badour std_strlcpy(sm->uri, uri, len);
221*418b791dSBob Badour sm->invoke = invoke;
222*418b791dSBob Badour sm->handle_invoke = handle_invoke;
223*418b791dSBob Badour RW_MUTEX_LOCK_WRITE(me->mut);
224*418b791dSBob Badour HASH_ADD_STR(*tbl, uri, sm);
225*418b791dSBob Badour RW_MUTEX_UNLOCK_WRITE(me->mut);
226*418b791dSBob Badour bail:
227*418b791dSBob Badour if(nErr != AEE_SUCCESS) {
228*418b791dSBob Badour VERIFY_EPRINTF("Error %x: static module addition failed\n", nErr);
229*418b791dSBob Badour if(sm) {
230*418b791dSBob Badour free(sm);
231*418b791dSBob Badour sm = NULL;
232*418b791dSBob Badour }
233*418b791dSBob Badour }
234*418b791dSBob Badour return nErr;
235*418b791dSBob Badour }
236*418b791dSBob Badour
static_mod_table_register_static_override(struct static_mod_table * me,const char * uri,int (* pfn)(uint32 sc,remote_arg * pra))237*418b791dSBob Badour static int static_mod_table_register_static_override(struct static_mod_table* me, const char* uri, int(*pfn)(uint32 sc, remote_arg* pra)) {
238*418b791dSBob Badour return static_mod_add(me, &me->staticModOverrides, uri, pfn, 0);
239*418b791dSBob Badour }
static_mod_table_register_static_override1(struct static_mod_table * me,const char * uri,int (* pfn)(remote_handle64,uint32 sc,remote_arg * pra))240*418b791dSBob Badour static int static_mod_table_register_static_override1(struct static_mod_table* me, const char* uri, int(*pfn)(remote_handle64, uint32 sc, remote_arg* pra)) {
241*418b791dSBob Badour return static_mod_add(me, &me->staticModOverrides, uri, 0, pfn);
242*418b791dSBob Badour }
static_mod_table_register_static(struct static_mod_table * me,const char * uri,int (* pfn)(uint32 sc,remote_arg * pra))243*418b791dSBob Badour static int static_mod_table_register_static(struct static_mod_table* me, const char* uri, int(*pfn)(uint32 sc, remote_arg* pra)) {
244*418b791dSBob Badour return static_mod_add(me, &me->staticMods, uri, pfn, 0);
245*418b791dSBob Badour }
static_mod_table_register_static1(struct static_mod_table * me,const char * uri,int (* pfn)(remote_handle64,uint32 sc,remote_arg * pra))246*418b791dSBob Badour static int static_mod_table_register_static1(struct static_mod_table* me, const char* uri, int(*pfn)(remote_handle64,uint32 sc, remote_arg* pra)) {
247*418b791dSBob Badour return static_mod_add(me, &me->staticMods, uri, 0, pfn);
248*418b791dSBob Badour }
249*418b791dSBob Badour
250*418b791dSBob Badour
static_mod_table_register_const_handle(struct static_mod_table * me,remote_handle local,remote_handle64 remote,const char * uri,int (* invoke)(uint32 sc,remote_arg * pra),int (* handle_invoke)(remote_handle64,uint32 sc,remote_arg * pra))251*418b791dSBob Badour static int static_mod_table_register_const_handle(struct static_mod_table* me, remote_handle local,
252*418b791dSBob Badour remote_handle64 remote, const char* uri,
253*418b791dSBob Badour int(*invoke)(uint32 sc, remote_arg* pra),
254*418b791dSBob Badour int(*handle_invoke)(remote_handle64, uint32 sc, remote_arg* pra)
255*418b791dSBob Badour ) {
256*418b791dSBob Badour int nErr = AEE_SUCCESS;
257*418b791dSBob Badour int len = std_strlen(uri) + 1;
258*418b791dSBob Badour struct const_mod *dm = 0, *dmOld;
259*418b791dSBob Badour VERIFYC(NULL != (dm = ((struct const_mod*)calloc(1, sizeof(struct open_mod) + len))), AEE_ENOMEMORY);
260*418b791dSBob Badour dm->key = local;
261*418b791dSBob Badour dm->invoke = invoke;
262*418b791dSBob Badour dm->handle_invoke = handle_invoke;
263*418b791dSBob Badour dm->h64 = remote;
264*418b791dSBob Badour std_strlcpy(dm->uri, uri, len);
265*418b791dSBob Badour
266*418b791dSBob Badour RW_MUTEX_LOCK_WRITE(me->mut);
267*418b791dSBob Badour HASH_FIND_INT(me->constMods, &local, dmOld);
268*418b791dSBob Badour if(dmOld == 0) {
269*418b791dSBob Badour HASH_ADD_INT(me->constMods, key, dm);
270*418b791dSBob Badour }
271*418b791dSBob Badour RW_MUTEX_UNLOCK_WRITE(me->mut);
272*418b791dSBob Badour nErr = dmOld != 0 ? -1 : nErr;
273*418b791dSBob Badour bail:
274*418b791dSBob Badour if(nErr != AEE_SUCCESS) {
275*418b791dSBob Badour VERIFY_EPRINTF("Error %x: failed to register const handle in modtable\n", nErr);
276*418b791dSBob Badour if(dm) {
277*418b791dSBob Badour free(dm);
278*418b791dSBob Badour dm = NULL;
279*418b791dSBob Badour }
280*418b791dSBob Badour }
281*418b791dSBob Badour return nErr;
282*418b791dSBob Badour }
283*418b791dSBob Badour
open_mod_handle_open(struct open_mod * mod,const char * name,remote_handle64 * ph)284*418b791dSBob Badour static int open_mod_handle_open(struct open_mod *mod, const char* name,
285*418b791dSBob Badour remote_handle64 *ph) {
286*418b791dSBob Badour int nErr = AEE_SUCCESS;
287*418b791dSBob Badour remote_arg args[3];
288*418b791dSBob Badour int32_t len = strlen(name) + 1;
289*418b791dSBob Badour args[0].buf.pv = &len;
290*418b791dSBob Badour args[0].buf.nLen = sizeof(len);
291*418b791dSBob Badour args[1].buf.pv = (void*)name;
292*418b791dSBob Badour args[1].buf.nLen = len;
293*418b791dSBob Badour nErr = mod->handle_invoke(0,REMOTE_SCALARS_MAKEX(0,0,2,0,0,1),args);
294*418b791dSBob Badour if(!nErr) {
295*418b791dSBob Badour *ph = args[2].h64;
296*418b791dSBob Badour }
297*418b791dSBob Badour FARF(HIGH, "allocated %x", *ph);
298*418b791dSBob Badour return nErr;
299*418b791dSBob Badour }
300*418b791dSBob Badour
open_mod_handle_close(struct open_mod * mod,remote_handle64 h)301*418b791dSBob Badour static int open_mod_handle_close(struct open_mod *mod, remote_handle64 h) {
302*418b791dSBob Badour int nErr;
303*418b791dSBob Badour remote_arg args[1];
304*418b791dSBob Badour args[0].h64 = h;
305*418b791dSBob Badour FARF(HIGH, "releasing %x", h);
306*418b791dSBob Badour nErr = mod->handle_invoke(0,REMOTE_SCALARS_MAKEX(0,1,0,0,1,0),args);
307*418b791dSBob Badour return nErr;
308*418b791dSBob Badour }
309*418b791dSBob Badour
notqmark(struct sbuf * buf)310*418b791dSBob Badour static int notqmark(struct sbuf *buf) {
311*418b791dSBob Badour return sbuf_notchar(buf, '?');
312*418b791dSBob Badour }
notandoreq(struct sbuf * buf)313*418b791dSBob Badour static int notandoreq(struct sbuf *buf) {
314*418b791dSBob Badour return sbuf_notchars(buf, "&=");
315*418b791dSBob Badour }
notand(struct sbuf * buf)316*418b791dSBob Badour static int notand(struct sbuf *buf) {
317*418b791dSBob Badour return sbuf_notchar(buf, '&');
318*418b791dSBob Badour }
319*418b791dSBob Badour
parse_uri(const char * uri,int urilen,struct parsed_uri * out)320*418b791dSBob Badour static int parse_uri(const char *uri, int urilen, struct parsed_uri *out) {
321*418b791dSBob Badour // "file:///librhtest_skel.so?rhtest_skel_handle_invoke&_modver=1.0"
322*418b791dSBob Badour int nErr = 0;
323*418b791dSBob Badour char *name, *value;
324*418b791dSBob Badour int nameLen, valueLen;
325*418b791dSBob Badour struct sbuf buf;
326*418b791dSBob Badour FARF(HIGH, "parse_uri %s %d", uri, urilen);
327*418b791dSBob Badour memset(out, 0, sizeof(*out));
328*418b791dSBob Badour //initialize
329*418b791dSBob Badour sbuf_parser_init(&buf, uri, urilen);
330*418b791dSBob Badour
331*418b791dSBob Badour //parse until question mark
332*418b791dSBob Badour VERIFYC(sbuf_string(&buf, "file://"), AEE_EINVALIDFORMAT);
333*418b791dSBob Badour
334*418b791dSBob Badour //ignore the starting /
335*418b791dSBob Badour (void)sbuf_string(&buf, "/");
336*418b791dSBob Badour
337*418b791dSBob Badour out->file = sbuf_cur(&buf);
338*418b791dSBob Badour VERIFY(sbuf_many1(&buf, notqmark));
339*418b791dSBob Badour out->filelen = sbuf_cur(&buf) - out->file;
340*418b791dSBob Badour FARF(HIGH, "file:%.*s %d", out->filelen, out->file, out->filelen);
341*418b791dSBob Badour VERIFY(sbuf_char(&buf, '?'));
342*418b791dSBob Badour out->sym = sbuf_cur(&buf);
343*418b791dSBob Badour VERIFY(sbuf_many1(&buf, notand));
344*418b791dSBob Badour out->symlen = sbuf_cur(&buf) - out->sym;
345*418b791dSBob Badour assert(out->sym + out->symlen <= uri + urilen);
346*418b791dSBob Badour FARF(HIGH, "sym:%.*s %d", out->symlen, out->sym, out->symlen);
347*418b791dSBob Badour
348*418b791dSBob Badour if(!sbuf_end(&buf) && sbuf_char(&buf, '&')) {
349*418b791dSBob Badour //parse each query
350*418b791dSBob Badour while(!sbuf_end(&buf)) {
351*418b791dSBob Badour //record where the name starts
352*418b791dSBob Badour name = sbuf_cur(&buf);
353*418b791dSBob Badour
354*418b791dSBob Badour //name is valid until '=' or '&'
355*418b791dSBob Badour VERIFY(sbuf_many1(&buf, notandoreq));
356*418b791dSBob Badour nameLen = sbuf_cur(&buf) - name;
357*418b791dSBob Badour
358*418b791dSBob Badour value = 0;
359*418b791dSBob Badour valueLen = 0;
360*418b791dSBob Badour //if the next char is a '=' then we also get a value
361*418b791dSBob Badour if(sbuf_char(&buf, '=')) {
362*418b791dSBob Badour value = sbuf_cur(&buf);
363*418b791dSBob Badour
364*418b791dSBob Badour //value is until the next query that starts with '&'
365*418b791dSBob Badour VERIFY(sbuf_many1(&buf, notand));
366*418b791dSBob Badour valueLen = sbuf_cur(&buf) - value;
367*418b791dSBob Badour }
368*418b791dSBob Badour //expect '&' or end
369*418b791dSBob Badour sbuf_char(&buf, '&');
370*418b791dSBob Badour if(!std_strncmp(name, "_modver", nameLen)) {
371*418b791dSBob Badour out->ver = value;
372*418b791dSBob Badour out->verlen = valueLen;
373*418b791dSBob Badour }
374*418b791dSBob Badour }
375*418b791dSBob Badour }
376*418b791dSBob Badour bail:
377*418b791dSBob Badour if(out->filelen) {
378*418b791dSBob Badour FARF(HIGH, "parse_uri file: %.*s", out->filelen, out->file);
379*418b791dSBob Badour }
380*418b791dSBob Badour if(out->symlen) {
381*418b791dSBob Badour FARF(HIGH, "parse_uri sym: %.*s", out->symlen, out->sym);
382*418b791dSBob Badour }
383*418b791dSBob Badour if(out->verlen) {
384*418b791dSBob Badour FARF(HIGH, "parse_uri version: %.*s", out->verlen, out->ver);
385*418b791dSBob Badour }
386*418b791dSBob Badour FARF(HIGH, "parse_uri done: %s %d err:%x", uri, urilen, nErr);
387*418b791dSBob Badour if(nErr != AEE_SUCCESS) {
388*418b791dSBob Badour VERIFY_EPRINTF("Error %x: parseuri failed for uri %s, urilen %d\n", nErr, uri, urilen);
389*418b791dSBob Badour }
390*418b791dSBob Badour return nErr;
391*418b791dSBob Badour }
392*418b791dSBob Badour
open_mod_table_open_dynamic(struct open_mod_table * me,const char * uri,remote_handle * handle,char * dlStr,int dlerrorLen,int * pdlErr)393*418b791dSBob Badour static int open_mod_table_open_dynamic(struct open_mod_table* me, const char* uri, remote_handle* handle, char* dlStr, int dlerrorLen, int* pdlErr)
394*418b791dSBob Badour {
395*418b791dSBob Badour int nErr = AEE_SUCCESS, dlErr = 0;
396*418b791dSBob Badour struct open_mod *dm = 0, *dmOld;
397*418b791dSBob Badour int len = strlen(uri);
398*418b791dSBob Badour int tmplen = len*2 + sizeof("file:///lib_skel.so?_skel_handle_invoke&_modver=1.0") + 1;
399*418b791dSBob Badour char *tmp = 0;
400*418b791dSBob Badour FARF(HIGH, "open_mod_table_open_dynamic");
401*418b791dSBob Badour VERIFYC(NULL != (tmp = calloc(1, tmplen)), AEE_ENOMEMORY);
402*418b791dSBob Badour VERIFYC(NULL != (dm = ((struct open_mod*)calloc(1, sizeof(struct open_mod) + len + 1))), AEE_ENOMEMORY);
403*418b791dSBob Badour std_memmove(dm->uri, uri, len + 1);
404*418b791dSBob Badour FARF(HIGH, "calling parse_uri");
405*418b791dSBob Badour (void)parse_uri(dm->uri, len, &dm->vals);
406*418b791dSBob Badour FARF(HIGH, "done calling parse_uri");
407*418b791dSBob Badour FARF(HIGH, "vals %d %d %d", dm->vals.filelen, dm->vals.symlen, dm->vals.verlen);
408*418b791dSBob Badour if(dm->vals.filelen) {
409*418b791dSBob Badour int rv = std_snprintf(tmp, tmplen, "%.*s", dm->vals.filelen, dm->vals.file);
410*418b791dSBob Badour VERIFYC(tmplen >= rv, AEE_EBADSIZE);
411*418b791dSBob Badour } else {
412*418b791dSBob Badour int rv;
413*418b791dSBob Badour rv = std_snprintf(tmp, tmplen, "lib%s_skel.so", uri);
414*418b791dSBob Badour VERIFYC(tmplen >= rv, AEE_EBADSIZE);
415*418b791dSBob Badour }
416*418b791dSBob Badour FARF(HIGH, "calling dlopen for %s", tmp);
417*418b791dSBob Badour dm->dlhandle = DLOPEN(tmp,RTLD_NOW);
418*418b791dSBob Badour FARF(HIGH, "got %p for dlopen %s", dm->dlhandle, tmp);
419*418b791dSBob Badour VERIFY(!(nErr = (dlErr = dm->dlhandle == 0 ? -5 : 0)));
420*418b791dSBob Badour
421*418b791dSBob Badour if(dm->vals.symlen) {
422*418b791dSBob Badour int rv = std_snprintf(tmp, tmplen, "%.*s", dm->vals.symlen, dm->vals.sym);
423*418b791dSBob Badour VERIFYC(tmplen >= rv, AEE_EBADSIZE);
424*418b791dSBob Badour } else {
425*418b791dSBob Badour int rv = std_snprintf(tmp, tmplen, "%s_skel_invoke", uri);
426*418b791dSBob Badour VERIFYC(tmplen >= rv, AEE_EBADSIZE);
427*418b791dSBob Badour }
428*418b791dSBob Badour
429*418b791dSBob Badour FARF(HIGH, "calling dlsym for %s", tmp);
430*418b791dSBob Badour if(dm->vals.verlen && 0 == std_strncmp(dm->vals.ver, "1.0", dm->vals.verlen)) {
431*418b791dSBob Badour dm->handle_invoke = (handle_invoke_fn) DLSYM(dm->dlhandle, tmp);
432*418b791dSBob Badour } else {
433*418b791dSBob Badour dm->invoke = (invoke_fn) DLSYM(dm->dlhandle, tmp);
434*418b791dSBob Badour }
435*418b791dSBob Badour FARF(HIGH, "dlsym returned %p %p", dm->invoke, dm->handle_invoke);
436*418b791dSBob Badour VERIFYC(!(dlErr = dm->invoke || dm->handle_invoke ? 0 : AEE_ENOSUCHSYMBOL), AEE_ENOSUCHSYMBOL);
437*418b791dSBob Badour
438*418b791dSBob Badour dm->key = (uint32)(uintptr_t)dm;
439*418b791dSBob Badour dm->refs = 1;
440*418b791dSBob Badour if(dm->handle_invoke) {
441*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = open_mod_handle_open(dm, uri, &dm->h64)));
442*418b791dSBob Badour }
443*418b791dSBob Badour RW_MUTEX_LOCK_WRITE(me->mut);
444*418b791dSBob Badour do {
445*418b791dSBob Badour HASH_FIND_INT(me->openMods, &dm->key, dmOld);
446*418b791dSBob Badour if(dmOld) {
447*418b791dSBob Badour dm->key++;
448*418b791dSBob Badour }
449*418b791dSBob Badour } while(dmOld);
450*418b791dSBob Badour RW_MUTEX_LOCK_WRITE(me->smt->mut);
451*418b791dSBob Badour HASH_FIND_INT(me->smt->constMods, &dm->key, dmOld);
452*418b791dSBob Badour RW_MUTEX_UNLOCK_WRITE(me->smt->mut);
453*418b791dSBob Badour if(dmOld == 0) {
454*418b791dSBob Badour HASH_ADD_INT(me->openMods, key, dm);
455*418b791dSBob Badour }
456*418b791dSBob Badour RW_MUTEX_UNLOCK_WRITE(me->mut);
457*418b791dSBob Badour nErr = dmOld != 0 ? -1 : nErr;
458*418b791dSBob Badour if(nErr == 0) {
459*418b791dSBob Badour *handle = dm->key;
460*418b791dSBob Badour }
461*418b791dSBob Badour bail:
462*418b791dSBob Badour if (nErr != AEE_SUCCESS) {
463*418b791dSBob Badour if(dlErr) {
464*418b791dSBob Badour const char* dlerr = DLERROR();
465*418b791dSBob Badour if(dlerr != 0){
466*418b791dSBob Badour std_strlcpy(dlStr,dlerr,dlerrorLen);
467*418b791dSBob Badour }
468*418b791dSBob Badour FARF(HIGH, "dlerror:%x:%s", dlErr, dlerr == 0 ? "" : dlerr);
469*418b791dSBob Badour nErr = 0;
470*418b791dSBob Badour }
471*418b791dSBob Badour if(pdlErr) {
472*418b791dSBob Badour *pdlErr = dlErr;
473*418b791dSBob Badour }
474*418b791dSBob Badour if(dm && dm->h64) {
475*418b791dSBob Badour (void)open_mod_handle_close(dm, dm->h64);
476*418b791dSBob Badour }
477*418b791dSBob Badour if(dm && dm->dlhandle) {
478*418b791dSBob Badour DLCLOSE(dm->dlhandle);
479*418b791dSBob Badour }
480*418b791dSBob Badour if(dm) {
481*418b791dSBob Badour free(dm);
482*418b791dSBob Badour dm = NULL;
483*418b791dSBob Badour }
484*418b791dSBob Badour VERIFY_EPRINTF("Error %x: open modtable dynamic failed. dlerr %x\n", nErr, dlErr);
485*418b791dSBob Badour }
486*418b791dSBob Badour FARF(HIGH, "done open_mod_table_open_dynamic for %s rv %x handle: %p %x", uri, nErr, *handle, dlErr);
487*418b791dSBob Badour if(tmp) {
488*418b791dSBob Badour free(tmp);
489*418b791dSBob Badour tmp = NULL;
490*418b791dSBob Badour }
491*418b791dSBob Badour return nErr;
492*418b791dSBob Badour }
493*418b791dSBob Badour
open_mod_table_open_from_static(struct open_mod_table * me,struct static_mod ** tbl,const char * uri,remote_handle * handle)494*418b791dSBob Badour static int open_mod_table_open_from_static(struct open_mod_table* me,
495*418b791dSBob Badour struct static_mod** tbl,
496*418b791dSBob Badour const char* uri,
497*418b791dSBob Badour remote_handle* handle)
498*418b791dSBob Badour {
499*418b791dSBob Badour int nErr = AEE_SUCCESS;
500*418b791dSBob Badour struct static_mod *sm = 0;
501*418b791dSBob Badour struct open_mod *dm = 0, *dmOld = 0;
502*418b791dSBob Badour int len = std_strlen(uri);
503*418b791dSBob Badour int sz = len*2 + sizeof("file:///lib_skel.so?_skel_handle_invoke&_modver=1.0") + 1;
504*418b791dSBob Badour char *tmp = 0;
505*418b791dSBob Badour VERIFYC(NULL != (dm = ((struct open_mod*)calloc(1, sizeof(*dm) + sz))), AEE_ENOMEMORY);
506*418b791dSBob Badour RW_MUTEX_LOCK_READ(me->mut);
507*418b791dSBob Badour HASH_FIND_STR(*tbl, uri, sm);
508*418b791dSBob Badour RW_MUTEX_UNLOCK_READ(me->mut);
509*418b791dSBob Badour std_memmove(dm->uri, uri, len);
510*418b791dSBob Badour if(sm == 0) {
511*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = parse_uri(uri, len, &dm->vals)));
512*418b791dSBob Badour FARF(HIGH, "file %.*s %d", dm->vals.filelen, dm->vals.file, dm->vals.filelen);
513*418b791dSBob Badour FARF(HIGH, "sym %.*s %d", dm->vals.symlen, dm->vals.sym, dm->vals.symlen);
514*418b791dSBob Badour FARF(HIGH, "version %.*s %d", dm->vals.verlen, dm->vals.ver, dm->vals.verlen);
515*418b791dSBob Badour if(dm->vals.verlen) {
516*418b791dSBob Badour int rv = std_snprintf(dm->uri, sz, "file:///%.*s?%.*s&_modver=%.*s",
517*418b791dSBob Badour dm->vals.filelen, dm->vals.file,
518*418b791dSBob Badour dm->vals.symlen, dm->vals.sym,
519*418b791dSBob Badour dm->vals.verlen, dm->vals.ver);
520*418b791dSBob Badour VERIFYC(sz >= rv, AEE_EBADSIZE);
521*418b791dSBob Badour } else {
522*418b791dSBob Badour int rv = std_snprintf(dm->uri, sz, "file://%.*s?%.*s",
523*418b791dSBob Badour dm->vals.filelen, dm->vals.file,
524*418b791dSBob Badour dm->vals.symlen, dm->vals.sym);
525*418b791dSBob Badour VERIFYC(sz >= rv, AEE_EBADSIZE);
526*418b791dSBob Badour }
527*418b791dSBob Badour FARF(HIGH, "dm->uri:%s", dm->uri);
528*418b791dSBob Badour
529*418b791dSBob Badour RW_MUTEX_LOCK_READ(me->mut);
530*418b791dSBob Badour HASH_FIND_STR(*tbl, dm->uri, sm);
531*418b791dSBob Badour RW_MUTEX_UNLOCK_READ(me->mut);
532*418b791dSBob Badour }
533*418b791dSBob Badour VERIFYC(0 != sm, AEE_ENOTINITIALIZED);
534*418b791dSBob Badour assert(sm->handle_invoke || sm->invoke);
535*418b791dSBob Badour dm->handle_invoke = sm->handle_invoke;
536*418b791dSBob Badour dm->invoke = sm->invoke;
537*418b791dSBob Badour dm->key = (uint32)(uintptr_t)dm;
538*418b791dSBob Badour dm->refs = 1;
539*418b791dSBob Badour if(dm->handle_invoke) {
540*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = open_mod_handle_open(dm, uri, &dm->h64)));
541*418b791dSBob Badour }
542*418b791dSBob Badour
543*418b791dSBob Badour RW_MUTEX_LOCK_WRITE(me->mut);
544*418b791dSBob Badour do {
545*418b791dSBob Badour HASH_FIND_INT(me->openMods, &dm->key, dmOld);
546*418b791dSBob Badour if(dmOld) {
547*418b791dSBob Badour dm->key++;
548*418b791dSBob Badour }
549*418b791dSBob Badour } while(dmOld);
550*418b791dSBob Badour HASH_ADD_INT(me->openMods, key, dm);
551*418b791dSBob Badour RW_MUTEX_UNLOCK_WRITE(me->mut);
552*418b791dSBob Badour
553*418b791dSBob Badour *handle = dm->key;
554*418b791dSBob Badour bail:
555*418b791dSBob Badour if(tmp) {
556*418b791dSBob Badour free(tmp);
557*418b791dSBob Badour tmp = NULL;
558*418b791dSBob Badour }
559*418b791dSBob Badour if(nErr != AEE_SUCCESS) {
560*418b791dSBob Badour VERIFY_EPRINTF("Error %x: modtable open from static failed.\n", nErr);
561*418b791dSBob Badour }
562*418b791dSBob Badour if(nErr && dm) {
563*418b791dSBob Badour if(dm->h64) {
564*418b791dSBob Badour (void)open_mod_handle_close(dm, dm->h64);
565*418b791dSBob Badour }
566*418b791dSBob Badour free(dm);
567*418b791dSBob Badour dm = NULL;
568*418b791dSBob Badour }
569*418b791dSBob Badour return nErr;
570*418b791dSBob Badour }
571*418b791dSBob Badour
open_mod_table_open(struct open_mod_table * me,const char * uri,remote_handle * handle,char * dlerr,int dlerrorLen,int * pdlErr)572*418b791dSBob Badour static int open_mod_table_open(struct open_mod_table* me, const char* uri, remote_handle* handle, char* dlerr, int dlerrorLen, int* pdlErr)
573*418b791dSBob Badour {
574*418b791dSBob Badour int nErr = AEE_SUCCESS, dlErr = 0;
575*418b791dSBob Badour if(pdlErr) {
576*418b791dSBob Badour *pdlErr = 0;
577*418b791dSBob Badour }
578*418b791dSBob Badour if(0 != open_mod_table_open_static_override(me, uri, handle)) {
579*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = open_mod_table_open_dynamic(me, uri, handle, dlerr, dlerrorLen, &dlErr)));
580*418b791dSBob Badour if(dlErr != 0) {
581*418b791dSBob Badour FARF(HIGH, "dynammic open failed, trying static");
582*418b791dSBob Badour if(0 != open_mod_table_open_static(me, uri, handle)) {
583*418b791dSBob Badour if(pdlErr) {
584*418b791dSBob Badour *pdlErr = dlErr;
585*418b791dSBob Badour }
586*418b791dSBob Badour }
587*418b791dSBob Badour }
588*418b791dSBob Badour }
589*418b791dSBob Badour bail:
590*418b791dSBob Badour FARF(HIGH, "done open for %s rv %d handle: %p", uri, nErr, *handle);
591*418b791dSBob Badour if(nErr != AEE_SUCCESS) {
592*418b791dSBob Badour VERIFY_EPRINTF("Error %x: open modtable failed\n", nErr);
593*418b791dSBob Badour }
594*418b791dSBob Badour return nErr;
595*418b791dSBob Badour }
596*418b791dSBob Badour
open_mod_close(struct open_mod_table * me,struct open_mod * dm)597*418b791dSBob Badour static void open_mod_close(struct open_mod_table *me, struct open_mod* dm) {
598*418b791dSBob Badour RW_MUTEX_LOCK_WRITE(me->mut);
599*418b791dSBob Badour dm->refs--;
600*418b791dSBob Badour if(dm->refs <= 0) {
601*418b791dSBob Badour HASH_DEL(me->openMods,dm);
602*418b791dSBob Badour } else {
603*418b791dSBob Badour dm = 0;
604*418b791dSBob Badour }
605*418b791dSBob Badour RW_MUTEX_UNLOCK_WRITE(me->mut);
606*418b791dSBob Badour if(dm) {
607*418b791dSBob Badour if(dm->h64) {
608*418b791dSBob Badour (void)open_mod_handle_close(dm, dm->h64);
609*418b791dSBob Badour }
610*418b791dSBob Badour if(dm->dlhandle) {
611*418b791dSBob Badour DLCLOSE(dm->dlhandle);
612*418b791dSBob Badour }
613*418b791dSBob Badour free(dm);
614*418b791dSBob Badour dm = NULL;
615*418b791dSBob Badour }
616*418b791dSBob Badour }
open_mod_table_close(struct open_mod_table * me,remote_handle64 handle,char * errStr,int errStrLen,int * pdlErr)617*418b791dSBob Badour static int open_mod_table_close(struct open_mod_table* me, remote_handle64 handle, char* errStr, int errStrLen, int* pdlErr)
618*418b791dSBob Badour {
619*418b791dSBob Badour int nErr = AEE_SUCCESS;
620*418b791dSBob Badour struct open_mod *dm, *del = 0;;
621*418b791dSBob Badour int dlErr = 0;
622*418b791dSBob Badour // First ensure that the handle is valid
623*418b791dSBob Badour RW_MUTEX_LOCK_WRITE(me->mut);
624*418b791dSBob Badour HASH_FIND_INT(me->openMods, &handle, dm);
625*418b791dSBob Badour if(dm) {
626*418b791dSBob Badour dm->refs--;
627*418b791dSBob Badour if(dm->refs <= 0) {
628*418b791dSBob Badour del = dm;
629*418b791dSBob Badour FARF(HIGH, "deleting %s %p", del->uri, del);
630*418b791dSBob Badour HASH_DEL(me->openMods,dm);
631*418b791dSBob Badour } else {
632*418b791dSBob Badour FARF(HIGH, "leaked %s", dm->uri);
633*418b791dSBob Badour dm = 0;
634*418b791dSBob Badour }
635*418b791dSBob Badour }
636*418b791dSBob Badour RW_MUTEX_UNLOCK_WRITE(me->mut);
637*418b791dSBob Badour if(del) {
638*418b791dSBob Badour if(del->h64) {
639*418b791dSBob Badour (void)open_mod_handle_close(dm, dm->h64);
640*418b791dSBob Badour }
641*418b791dSBob Badour if(del->dlhandle) {
642*418b791dSBob Badour dlErr = DLCLOSE(del->dlhandle);
643*418b791dSBob Badour }
644*418b791dSBob Badour FARF(HIGH, "free %s %p", del->uri, del);
645*418b791dSBob Badour free(del);
646*418b791dSBob Badour del = NULL;
647*418b791dSBob Badour }
648*418b791dSBob Badour VERIFY(del);
649*418b791dSBob Badour
650*418b791dSBob Badour bail:
651*418b791dSBob Badour if(dlErr) {
652*418b791dSBob Badour const char* error = DLERROR();
653*418b791dSBob Badour nErr = dlErr;
654*418b791dSBob Badour if(error != 0){
655*418b791dSBob Badour std_strlcpy(errStr,error,errStrLen);
656*418b791dSBob Badour }
657*418b791dSBob Badour VERIFY_EPRINTF("Error %x: open modtable close failed. dlerr %s\n", nErr, error);
658*418b791dSBob Badour }
659*418b791dSBob Badour if(pdlErr) {
660*418b791dSBob Badour *pdlErr = dlErr;
661*418b791dSBob Badour }
662*418b791dSBob Badour return nErr;
663*418b791dSBob Badour }
664*418b791dSBob Badour
open_mod_table_get_open(struct open_mod_table * me,remote_handle handle)665*418b791dSBob Badour static struct open_mod* open_mod_table_get_open(struct open_mod_table* me, remote_handle handle) {
666*418b791dSBob Badour struct open_mod* om = 0;
667*418b791dSBob Badour RW_MUTEX_LOCK_READ(me->mut);
668*418b791dSBob Badour HASH_FIND_INT(me->openMods, &handle, om);
669*418b791dSBob Badour if(0 != om) {
670*418b791dSBob Badour om->refs++;
671*418b791dSBob Badour }
672*418b791dSBob Badour RW_MUTEX_UNLOCK_READ(me->mut);
673*418b791dSBob Badour return om;
674*418b791dSBob Badour }
open_mod_table_get_const(struct open_mod_table * me,remote_handle handle)675*418b791dSBob Badour static struct const_mod* open_mod_table_get_const(struct open_mod_table* me, remote_handle handle) {
676*418b791dSBob Badour struct const_mod* cm = 0;
677*418b791dSBob Badour RW_MUTEX_LOCK_READ(me->smt->mut);
678*418b791dSBob Badour HASH_FIND_INT(me->smt->constMods, &handle, cm);
679*418b791dSBob Badour RW_MUTEX_UNLOCK_READ(me->smt->mut);
680*418b791dSBob Badour return cm;
681*418b791dSBob Badour }
682*418b791dSBob Badour
open_mod_table_handle_invoke(struct open_mod_table * me,remote_handle handle,uint32 sc,remote_arg * pra)683*418b791dSBob Badour static int open_mod_table_handle_invoke(struct open_mod_table* me, remote_handle handle, uint32 sc, remote_arg* pra) {
684*418b791dSBob Badour int nErr = AEE_SUCCESS;
685*418b791dSBob Badour struct open_mod* om = 0;
686*418b791dSBob Badour struct const_mod* cm = 0;
687*418b791dSBob Badour remote_handle64 h = 0;
688*418b791dSBob Badour invoke_fn invoke = 0;
689*418b791dSBob Badour handle_invoke_fn handle_invoke = 0;
690*418b791dSBob Badour cm = open_mod_table_get_const(me, handle);
691*418b791dSBob Badour if(cm) {
692*418b791dSBob Badour invoke = cm->invoke;
693*418b791dSBob Badour handle_invoke = cm->handle_invoke;
694*418b791dSBob Badour h = cm->h64;
695*418b791dSBob Badour } else {
696*418b791dSBob Badour VERIFYC(0 != (om = open_mod_table_get_open(me, handle)), AEE_ENOSUCHMOD);
697*418b791dSBob Badour invoke = om->invoke;
698*418b791dSBob Badour handle_invoke = om->handle_invoke;
699*418b791dSBob Badour h = om->h64;
700*418b791dSBob Badour }
701*418b791dSBob Badour if(invoke) {
702*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = invoke(sc, pra)));
703*418b791dSBob Badour } else {
704*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = handle_invoke(h, sc, pra)));
705*418b791dSBob Badour }
706*418b791dSBob Badour bail:
707*418b791dSBob Badour if(om) {
708*418b791dSBob Badour open_mod_close(me, om);
709*418b791dSBob Badour }
710*418b791dSBob Badour FARF(HIGH, "invoke rv %p %x %x", handle, sc, nErr);
711*418b791dSBob Badour return nErr;
712*418b791dSBob Badour }
713*418b791dSBob Badour
714*418b791dSBob Badour struct mod_table {
715*418b791dSBob Badour struct static_mod_table smt;
716*418b791dSBob Badour struct open_mod_table omt;
717*418b791dSBob Badour };
718*418b791dSBob Badour
719*418b791dSBob Badour // mod_table object
720*418b791dSBob Badour static struct static_mod_table static_mod_table_obj;
721*418b791dSBob Badour
722*418b791dSBob Badour
723*418b791dSBob Badour /**
724*418b791dSBob Badour * register a static component for invocations
725*418b791dSBob Badour * this can be called at any time including from a static constructor
726*418b791dSBob Badour *
727*418b791dSBob Badour * overrides will be tried first, then dynamic modules, then regular
728*418b791dSBob Badour * static modules.
729*418b791dSBob Badour *
730*418b791dSBob Badour * name, name of the interface to register
731*418b791dSBob Badour * pfn, function pointer to the skel invoke function
732*418b791dSBob Badour *
733*418b791dSBob Badour * for example:
734*418b791dSBob Badour * __attribute__((constructor)) static void my_module_ctor(void) {
735*418b791dSBob Badour * mod_table_register_static("my_module", my_module_skel_invoke);
736*418b791dSBob Badour * }
737*418b791dSBob Badour *
738*418b791dSBob Badour */
mod_table_register_static_override(const char * name,int (* pfn)(uint32 sc,remote_arg * pra))739*418b791dSBob Badour int mod_table_register_static_override(const char* name, int(*pfn)(uint32 sc, remote_arg* pra)) {
740*418b791dSBob Badour if(0 == static_mod_table_ctor(&static_mod_table_obj)) {
741*418b791dSBob Badour return static_mod_table_register_static_override(&static_mod_table_obj, name, pfn);
742*418b791dSBob Badour }
743*418b791dSBob Badour return AEE_EUNKNOWN;
744*418b791dSBob Badour }
745*418b791dSBob Badour
mod_table_register_static_override1(const char * name,int (* pfn)(remote_handle64,uint32 sc,remote_arg * pra))746*418b791dSBob Badour int mod_table_register_static_override1(const char* name, int(*pfn)(remote_handle64, uint32 sc, remote_arg* pra)) {
747*418b791dSBob Badour if(0 == static_mod_table_ctor(&static_mod_table_obj)) {
748*418b791dSBob Badour return static_mod_table_register_static_override1(&static_mod_table_obj, name, pfn);
749*418b791dSBob Badour }
750*418b791dSBob Badour return AEE_EUNKNOWN;
751*418b791dSBob Badour }
752*418b791dSBob Badour
753*418b791dSBob Badour
754*418b791dSBob Badour /**
755*418b791dSBob Badour * register a static component for invocations
756*418b791dSBob Badour * this can be called at any time including from a static constructor
757*418b791dSBob Badour *
758*418b791dSBob Badour * name, name of the interface to register
759*418b791dSBob Badour * pfn, function pointer to the skel invoke function
760*418b791dSBob Badour *
761*418b791dSBob Badour * for example:
762*418b791dSBob Badour * __attribute__((constructor)) static void my_module_ctor(void) {
763*418b791dSBob Badour * mod_table_register_static("my_module", my_module_skel_invoke);
764*418b791dSBob Badour * }
765*418b791dSBob Badour *
766*418b791dSBob Badour */
mod_table_register_static(const char * name,int (* pfn)(uint32 sc,remote_arg * pra))767*418b791dSBob Badour int mod_table_register_static(const char* name, int(*pfn)(uint32 sc, remote_arg* pra)) {
768*418b791dSBob Badour if(0 == static_mod_table_ctor(&static_mod_table_obj)) {
769*418b791dSBob Badour return static_mod_table_register_static(&static_mod_table_obj, name, pfn);
770*418b791dSBob Badour }
771*418b791dSBob Badour return AEE_EUNKNOWN;
772*418b791dSBob Badour }
773*418b791dSBob Badour
mod_table_register_static1(const char * name,int (* pfn)(remote_handle64,uint32 sc,remote_arg * pra))774*418b791dSBob Badour int mod_table_register_static1(const char* name, int(*pfn)(remote_handle64, uint32 sc, remote_arg* pra)) {
775*418b791dSBob Badour if(0 == static_mod_table_ctor(&static_mod_table_obj)) {
776*418b791dSBob Badour return static_mod_table_register_static1(&static_mod_table_obj, name, pfn);
777*418b791dSBob Badour }
778*418b791dSBob Badour return AEE_EUNKNOWN;
779*418b791dSBob Badour }
780*418b791dSBob Badour
781*418b791dSBob Badour
782*418b791dSBob Badour /**
783*418b791dSBob Badour * Open a module and get a handle to it
784*418b791dSBob Badour *
785*418b791dSBob Badour * uri, name of module to open
786*418b791dSBob Badour * handle, Output handle
787*418b791dSBob Badour * dlerr, Error String (if an error occurs)
788*418b791dSBob Badour * dlerrorLen, Length of error String (if an error occurs)
789*418b791dSBob Badour * pdlErr, Error identifier
790*418b791dSBob Badour */
mod_table_open(const char * uri,remote_handle * handle,char * dlerr,int dlerrorLen,int * pdlErr)791*418b791dSBob Badour int mod_table_open(const char* uri, remote_handle* handle, char* dlerr, int dlerrorLen, int* pdlErr) {
792*418b791dSBob Badour int nErr = AEE_SUCCESS;
793*418b791dSBob Badour struct open_mod_table* pomt = 0;
794*418b791dSBob Badour FARF(HIGH, "mod_table_open for %s", uri);
795*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = HAP_pls_add_lookup((uintptr_t)open_mod_table_ctor_imp, 0, sizeof(*pomt), open_mod_table_ctor_imp, (void*)&static_mod_table_obj, open_mod_table_dtor_imp, (void**)&pomt)));
796*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = open_mod_table_open(pomt,uri,handle,dlerr,dlerrorLen,pdlErr)));
797*418b791dSBob Badour bail:
798*418b791dSBob Badour FARF(HIGH, "mod_table_open for %s nErr: %x", uri, nErr);
799*418b791dSBob Badour if(nErr != AEE_SUCCESS) {
800*418b791dSBob Badour VERIFY_EPRINTF("Error %x: modtable open failed\n", nErr);
801*418b791dSBob Badour }
802*418b791dSBob Badour return nErr;
803*418b791dSBob Badour }
804*418b791dSBob Badour /**
805*418b791dSBob Badour * invoke a handle in the mod table
806*418b791dSBob Badour *
807*418b791dSBob Badour * handle, handle to invoke
808*418b791dSBob Badour * sc, scalars, see remote.h for documentation.
809*418b791dSBob Badour * pra, args, see remote.h for documentation.
810*418b791dSBob Badour */
mod_table_invoke(remote_handle handle,uint32 sc,remote_arg * pra)811*418b791dSBob Badour int mod_table_invoke(remote_handle handle, uint32 sc, remote_arg* pra) {
812*418b791dSBob Badour int nErr = AEE_SUCCESS;
813*418b791dSBob Badour struct open_mod_table* pomt = 0;
814*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = HAP_pls_add_lookup((uintptr_t)open_mod_table_ctor_imp, 0, sizeof(*pomt), open_mod_table_ctor_imp, (void*)&static_mod_table_obj, open_mod_table_dtor_imp, (void**)&pomt)));
815*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = open_mod_table_handle_invoke(pomt, handle, sc, pra)));
816*418b791dSBob Badour bail:
817*418b791dSBob Badour return nErr;
818*418b791dSBob Badour }
819*418b791dSBob Badour
820*418b791dSBob Badour /**
821*418b791dSBob Badour * Closes a handle in the mod table
822*418b791dSBob Badour *
823*418b791dSBob Badour * handle, handle to close
824*418b791dSBob Badour * errStr, Error String (if an error occurs)
825*418b791dSBob Badour * errStrLen, Length of error String (if an error occurs)
826*418b791dSBob Badour * pdlErr, Error identifier
827*418b791dSBob Badour */
mod_table_close(remote_handle handle,char * errStr,int errStrLen,int * pdlErr)828*418b791dSBob Badour int mod_table_close(remote_handle handle, char* errStr, int errStrLen, int* pdlErr) {
829*418b791dSBob Badour int nErr = AEE_SUCCESS;
830*418b791dSBob Badour struct open_mod_table* pomt = 0;
831*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = HAP_pls_lookup((uintptr_t)open_mod_table_ctor_imp, 0, (void**)&pomt)));
832*418b791dSBob Badour VERIFY(AEE_SUCCESS == (nErr = open_mod_table_close(pomt, handle, errStr,errStrLen,pdlErr)));
833*418b791dSBob Badour bail:
834*418b791dSBob Badour if(nErr != AEE_SUCCESS) {
835*418b791dSBob Badour VERIFY_EPRINTF("Error %x: modtable close failed\n", nErr);
836*418b791dSBob Badour }
837*418b791dSBob Badour return nErr;
838*418b791dSBob Badour }
839*418b791dSBob Badour
840*418b791dSBob Badour /**
841*418b791dSBob Badour * internal use only
842*418b791dSBob Badour */
mod_table_register_const_handle(remote_handle remote,const char * uri,int (* pfn)(uint32 sc,remote_arg * pra))843*418b791dSBob Badour int mod_table_register_const_handle(remote_handle remote, const char* uri, int(*pfn)(uint32 sc, remote_arg* pra)) {
844*418b791dSBob Badour if(0 == static_mod_table_ctor(&static_mod_table_obj)) {
845*418b791dSBob Badour return static_mod_table_register_const_handle(&static_mod_table_obj, remote, 0, uri, pfn, 0);
846*418b791dSBob Badour }
847*418b791dSBob Badour return AEE_EUNKNOWN;
848*418b791dSBob Badour }
mod_table_register_const_handle1(remote_handle remote,remote_handle64 local,const char * uri,int (* pfn)(remote_handle64,uint32 sc,remote_arg * pra))849*418b791dSBob Badour int mod_table_register_const_handle1(remote_handle remote, remote_handle64 local, const char* uri, int(*pfn)(remote_handle64, uint32 sc, remote_arg* pra)) {
850*418b791dSBob Badour if(0 == static_mod_table_ctor(&static_mod_table_obj)) {
851*418b791dSBob Badour return static_mod_table_register_const_handle(&static_mod_table_obj, remote, local, uri, 0, pfn);
852*418b791dSBob Badour }
853*418b791dSBob Badour return AEE_EUNKNOWN;
854*418b791dSBob Badour }
855*418b791dSBob Badour
856*418b791dSBob Badour // Constructor and destructor
mod_table_ctor(void)857*418b791dSBob Badour static int mod_table_ctor(void) {
858*418b791dSBob Badour return static_mod_table_ctor(&static_mod_table_obj);
859*418b791dSBob Badour }
mod_table_dtor(void)860*418b791dSBob Badour static void mod_table_dtor(void) {
861*418b791dSBob Badour static_mod_table_dtor_imp(&static_mod_table_obj);
862*418b791dSBob Badour return;
863*418b791dSBob Badour }
864*418b791dSBob Badour
865*418b791dSBob Badour PL_DEFINE(mod_table, mod_table_ctor, mod_table_dtor);
866