@@ -27,16 +27,26 @@ var LibraryDylink = {
2727 return true ;
2828 } ,
2929
30+ // Resolve a global symbol by name. This is used during module loading to
31+ // resolve imports, and by `dlsym` when used with `RTLD_DEFAULT`.
32+ // Returns both the resolved symbol (i.e. a function or a global) along with
33+ // the canonical name of the symbol (in some cases is modify the symbol as
34+ // part of the loop process, so that actual symbol looked up has a different
35+ // name).
3036 $resolveGlobalSymbol__deps : [ '$isSymbolDefined' ] ,
3137 $resolveGlobalSymbol__internal : true ,
3238 $resolveGlobalSymbol : function ( symName , direct = false ) {
3339 var sym ;
3440#if ! WASM_BIGINT
35- if ( direct ) {
36- // First look for the orig$ symbol which is the symbols without
37- // any legalization performed.
38- sym = wasmImports [ 'orig$' + symName ] ;
39- if ( sym ) return sym ;
41+ // First look for the orig$ symbol which is the symbol without i64
42+ // legalization performed.
43+ if ( direct && ( 'orig$' + symName in wasmImports ) ) {
44+ symName = 'orig$' + symName ;
45+ }
46+ #endif
47+ #if ! DISABLE_EXCEPTION_CATCHING
48+ if ( symName . startsWith ( '__cxa_find_matching_catch_' ) ) {
49+ symName = '__cxa_find_matching_catch' ;
4050 }
4151#endif
4252 if ( isSymbolDefined ( symName ) ) {
@@ -45,12 +55,7 @@ var LibraryDylink = {
4555 // Create (and cache) new invoke_ functions on demand.
4656 sym = wasmImports [ symName ] = createInvokeFunction ( symName . split ( '_' ) [ 1 ] ) ;
4757 }
48- #if ! DISABLE_EXCEPTION_CATCHING
49- else if ( symName . startsWith ( '__cxa_find_matching_catch_' ) ) {
50- sym = wasmImports [ '__cxa_find_matching_catch' ] ;
51- }
52- #endif
53- return sym ;
58+ return { sym : sym , name : symName } ;
5459 } ,
5560
5661 $GOT : { } ,
@@ -104,7 +109,7 @@ var LibraryDylink = {
104109 } ,
105110
106111 $updateGOT__internal : true ,
107- $updateGOT__deps : [ '$GOT' , '$isInternalSym' , '$addFunction' ] ,
112+ $updateGOT__deps : [ '$GOT' , '$isInternalSym' , '$addFunction' , '$getFunctionAddress' ] ,
108113 $updateGOT : function ( exports , replace ) {
109114#if DYLINK_DEBUG
110115 dbg ( "updateGOT: adding " + Object . keys ( exports ) . length + " symbols" ) ;
@@ -192,7 +197,7 @@ var LibraryDylink = {
192197#endif
193198 for ( var symName in GOT ) {
194199 if ( GOT [ symName ] . value == 0 ) {
195- var value = resolveGlobalSymbol ( symName , true )
200+ var value = resolveGlobalSymbol ( symName , true ) . sym ;
196201 if ( ! value && ! GOT [ symName ] . required ) {
197202 // Ignore undefined symbols that are imported as weak.
198203#if DYLINK_DEBUG
@@ -234,13 +239,15 @@ var LibraryDylink = {
234239 _dlopen_js__deps: [ function ( ) { error ( dlopenMissingError ) ; } ] ,
235240 _emscripten_dlopen_js__deps : [ function ( ) { error ( dlopenMissingError ) ; } ] ,
236241 _dlsym_js__deps : [ function ( ) { error ( dlopenMissingError ) ; } ] ,
242+ _dlsym_catchup_js__deps : [ function ( ) { error ( dlopenMissingError ) ; } ] ,
237243#else
238244 $dlopenMissingError : `= ${ dlopenMissingError } ` ,
239245 _dlopen_js__deps : [ '$dlopenMissingError' ] ,
240246 _emscripten_dlopen_js__deps : [ '$dlopenMissingError' ] ,
241247 _dlsym_js__deps : [ '$dlopenMissingError' ] ,
248+ _dlsym_catchup_js__deps : [ '$dlopenMissingError' ] ,
242249#endif
243- _dlopen_js : function ( filename , flag ) {
250+ _dlopen_js : function ( handle ) {
244251 abort ( dlopenMissingError ) ;
245252 } ,
246253 _emscripten_dlopen_js : function ( handle , onsuccess , onerror , user_data ) {
@@ -249,6 +256,9 @@ var LibraryDylink = {
249256 _dlsym_js : function ( handle , symbol ) {
250257 abort ( dlopenMissingError ) ;
251258 } ,
259+ _dlsym_catchup_js : function ( handle , symbolIndex ) {
260+ abort ( dlopenMissingError ) ;
261+ } ,
252262 _dlinit : function ( main_dso_handle ) { } ,
253263#else // MAIN_MODULE != 0
254264 // dynamic linker/loader (a-la ld.so on ELF systems)
@@ -262,6 +272,9 @@ var LibraryDylink = {
262272 $dlSetError__internal : true ,
263273 $dlSetError__deps : [ '__dl_seterr' , '$allocateUTF8OnStack' , '$withStackSave' ] ,
264274 $dlSetError : function ( msg ) {
275+ #if DYLINK_DEBUG
276+ dbg ( 'dlSetError: ' + msg ) ;
277+ #endif
265278 withStackSave ( function ( ) {
266279 var cmsg = allocateUTF8OnStack ( msg ) ;
267280 ___dl_seterr ( cmsg , 0 ) ;
@@ -591,7 +604,7 @@ var LibraryDylink = {
591604 var moduleExports ;
592605
593606 function resolveSymbol ( sym ) {
594- var resolved = resolveGlobalSymbol ( sym ) ;
607+ var resolved = resolveGlobalSymbol ( sym ) . sym ;
595608 if ( ! resolved ) {
596609 resolved = moduleExports [ sym ] ;
597610 }
@@ -1061,21 +1074,46 @@ var LibraryDylink = {
10611074 }
10621075 } ,
10631076
1077+ _dlsym_catchup_js__sig : 'ppp' ,
1078+ _dlsym_catchup_js : function ( handle , symbolIndex ) {
1079+ #if DYLINK_DEBUG
1080+ dbg ( "_dlsym_catchup: handle=" + ptrToString ( handle ) + " symbolIndex=" + symbolIndex ) ;
1081+ #endif
1082+ var symDict = wasmImports ;
1083+ if ( handle != { { { cDefine ( 'RTLD_DEFAULT' ) } } } ) {
1084+ var lib = LDSO . loadedLibsByHandle [ handle ] ;
1085+ symDict = lib . module ;
1086+ }
1087+ var symName = Object . keys ( symDict ) [ symbolIndex ] ;
1088+ var sym = symDict [ symName ] ;
1089+ var result = addFunction ( sym , sym . sig ) ;
1090+ #if DYLINK_DEBUG
1091+ dbg ( '_dlsym_catchup: result=' + result ) ;
1092+ #endif
1093+ return result ;
1094+ } ,
1095+
10641096 // void* dlsym(void* handle, const char* symbol);
1065- _dlsym_js__deps : [ '$dlSetError' ] ,
1097+ _dlsym_js__deps : [ '$dlSetError' , '$getFunctionAddress' , '$addFunction' ] ,
10661098 _dlsym_js__sig : 'ppp' ,
1067- _dlsym_js : function ( handle , symbol ) {
1099+ _dlsym_js : function ( handle , symbol , symbolIndex ) {
10681100 // void *dlsym(void *restrict handle, const char *restrict name);
10691101 // http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html
10701102 symbol = UTF8ToString ( symbol ) ;
1103+ #if DYLINK_DEBUG
1104+ dbg ( 'dlsym_js: ' + symbol ) ;
1105+ #endif
10711106 var result ;
1107+ var newSymIndex ;
10721108
10731109 if ( handle == { { { cDefine ( 'RTLD_DEFAULT' ) } } } ) {
1074- result = resolveGlobalSymbol ( symbol , true ) ;
1110+ var resolved = resolveGlobalSymbol ( symbol , true ) ;
1111+ result = resolved . sym ;
10751112 if ( ! result ) {
10761113 dlSetError ( 'Tried to lookup unknown symbol "' + symbol + '" in dynamic lib: RTLD_DEFAULT' ) ;
10771114 return 0 ;
10781115 }
1116+ newSymIndex = Object . keys ( wasmImports ) . indexOf ( resolved . name ) ;
10791117 } else {
10801118 var lib = LDSO . loadedLibsByHandle [ handle ] ;
10811119#if ASSERTIONS
@@ -1085,16 +1123,21 @@ var LibraryDylink = {
10851123 dlSetError ( 'Tried to lookup unknown symbol "' + symbol + '" in dynamic lib: ' + lib . name )
10861124 return 0 ;
10871125 }
1126+ newSymIndex = Object . keys ( lib . module ) . indexOf ( symbol ) ;
10881127#if ! WASM_BIGINT
1089- result = lib . module [ 'orig$' + symbol ] ;
1090- if ( ! result )
1128+ var origSym = 'orig$' + symbol ;
1129+ result = lib . module [ origSym ] ;
1130+ if ( result ) {
1131+ newSymIndex = Object . keys ( lib . module ) . indexOf ( origSym ) ;
1132+ }
1133+ else
10911134#endif
10921135 result = lib . module [ symbol ] ;
10931136 }
10941137
10951138 if ( typeof result == 'function' ) {
10961139#if DYLINK_DEBUG
1097- dbg ( 'dlsym : ' + symbol + ' getting table slot for: ' + result ) ;
1140+ dbg ( 'dlsym_js : ' + symbol + ' getting table slot for: ' + result ) ;
10981141#endif
10991142
11001143#if ASYNCIFY
@@ -1103,14 +1146,26 @@ var LibraryDylink = {
11031146 result = result . orig ;
11041147 }
11051148#endif
1106- // Insert the function into the wasm table. If its a direct wasm function
1107- // the second argument will not be needed. If its a JS function we rely
1108- // on the `sig` attribute being set based on the `<func>__sig` specified
1109- // in library JS file.
1110- result = addFunction ( result , result . sig ) ;
1149+ var addr = getFunctionAddress ( result ) ;
1150+ if ( addr ) {
1151+ #if DYLINK_DEBUG
1152+ dbg ( 'symbol already exists in table: ' + symbol ) ;
1153+ #endif
1154+ result = addr ;
1155+ } else {
1156+ // Insert the function into the wasm table. If its a direct wasm
1157+ // function the second argument will not be needed. If its a JS
1158+ // function we rely on the `sig` attribute being set based on the
1159+ // `<func>__sig` specified in library JS file.
1160+ result = addFunction ( result , result . sig ) ;
1161+ #if DYLINK_DEBUG
1162+ dbg ( 'adding symbol to table: ' + symbol ) ;
1163+ #endif
1164+ { { { makeSetValue ( 'symbolIndex' , 0 , 'newSymIndex' , '*' ) } } } ;
1165+ }
11111166 }
11121167#if DYLINK_DEBUG
1113- dbg ( 'dlsym : ' + symbol + ' -> ' + result ) ;
1168+ dbg ( 'dlsym_js : ' + symbol + ' -> ' + result ) ;
11141169#endif
11151170 return result ;
11161171 } ,
0 commit comments