66 * Dynamic library loading
77 */
88
9- #if ! RELOCATABLE
10- #error "library_dylink.js requires RELOCATABLE"
9+ #if ! MAIN_MODULE && ! RELOCATABLE
10+ #error "library_dylink.js requires MAIN_MODULE or RELOCATABLE"
1111#endif
1212
1313var LibraryDylink = {
@@ -170,10 +170,10 @@ var LibraryDylink = {
170170 get ( obj , symName ) {
171171 var rtn = GOT [ symName ] ;
172172 if ( ! rtn ) {
173- rtn = GOT [ symName ] = new WebAssembly . Global ( { 'value' : '{{{ POINTER_WASM_TYPE }}}' , 'mutable' : true } ) ;
174173#if DYLINK_DEBUG == 2
175- dbg ( " new GOT entry: " + symName ) ;
174+ dbg ( ` new GOT entry: ${ symName } ` ) ;
176175#endif
176+ rtn = GOT [ symName ] = new WebAssembly . Global ( { 'value' : '{{{ POINTER_WASM_TYPE }}}' , 'mutable' : true } , { { { to64 ( - 1 ) } } } ) ;
177177 }
178178 if ( ! currentModuleWeakSymbols . has ( symName ) ) {
179179 // Any non-weak reference to a symbol marks it as `required`, which
@@ -189,6 +189,11 @@ var LibraryDylink = {
189189 $isInternalSym : ( symName ) => {
190190 // TODO: find a way to mark these in the binary or avoid exporting them.
191191 return [
192+ 'memory' ,
193+ '__memory_base' ,
194+ '__table_base' ,
195+ '__stack_pointer' ,
196+ '__indirect_function_table' ,
192197 '__cpp_exception' ,
193198 '__c_longjmp' ,
194199 '__wasm_apply_data_relocs' ,
@@ -213,6 +218,7 @@ var LibraryDylink = {
213218
214219 $updateGOT__internal : true ,
215220 $updateGOT__deps : [ '$GOT' , '$isInternalSym' , '$addFunction' ] ,
221+ $updateGOT__docs : '/** @param {boolean=} replace */' ,
216222 $updateGOT : ( exports , replace ) = > {
217223#if DYLINK_DEBUG
218224 dbg ( `updateGOT: adding ${ Object . keys ( exports ) . length } symbols` ) ;
@@ -230,8 +236,7 @@ var LibraryDylink = {
230236 }
231237#endif
232238
233-
234- var existingEntry = GOT [ symName ] && GOT [ symName ] . value != 0 ;
239+ var existingEntry = GOT [ symName ] && GOT [ symName ] . value != { { { to64 ( - 1 ) } } } ;
235240 if ( replace || ! existingEntry ) {
236241#if DYLINK_DEBUG == 2
237242 dbg ( `updateGOT: before: ${ symName } : ${ GOT [ symName ] ?. value } ` ) ;
@@ -252,7 +257,7 @@ var LibraryDylink = {
252257#if DYLINK_DEBUG == 2
253258 dbg ( `updateGOT: after: ${ symName } : ${ newValue } (${ value } )` ) ;
254259#endif
255- GOT [ symName ] || = new WebAssembly . Global ( { 'value' : '{{{ POINTER_WASM_TYPE }}}' , 'mutable' : true } ) ;
260+ GOT [ symName ] ?? = new WebAssembly . Global ( { 'value' : '{{{ POINTER_WASM_TYPE }}}' , 'mutable' : true } ) ;
256261 GOT [ symName ] . value = newValue ;
257262 }
258263#if DYLINK_DEBUG
@@ -280,9 +285,12 @@ var LibraryDylink = {
280285
281286 // Applies relocations to exported things.
282287 $relocateExports__internal : true ,
283- $relocateExports__deps : [ '$updateGOT' , '$isImmutableGlobal' ] ,
284- $relocateExports__docs : '/** @param {boolean=} replace */' ,
285- $relocateExports : ( exports , memoryBase , replace ) = > {
288+ $relocateExports__deps : [ '$isImmutableGlobal' ] ,
289+ $relocateExports : ( exports , memoryBase = 0 ) = > {
290+ #if DYLINK_DEBUG
291+ dbg ( `relocateExports memoryBase=${ memoryBase } count=${ Object . keys ( exports ) . length } ` ) ;
292+ #endif
293+
286294 function relocateExport ( name , value ) {
287295#if SPLIT_MODULE
288296 // Do not modify exports synthesized by wasm-split
@@ -304,7 +312,6 @@ var LibraryDylink = {
304312 for ( var e in exports ) {
305313 relocated [ e ] = relocateExport ( e , exports [ e ] )
306314 }
307- updateGOT ( relocated , replace ) ;
308315 return relocated ;
309316 } ,
310317
@@ -315,13 +322,17 @@ var LibraryDylink = {
315322 dbg ( 'reportUndefinedSymbols' ) ;
316323#endif
317324 for ( var [ symName , entry ] of Object . entries ( GOT ) ) {
318- if ( entry . value == 0 ) {
325+ if ( entry . value == { { { to64( - 1 ) } } } ) {
326+ #if DYLINK_DEBUG
327+ dbg ( `undef GOT entry: ${ symName } ` ) ;
328+ #endif
319329 var value = resolveGlobalSymbol ( symName , true ) . sym ;
320330 if ( ! value && ! entry . required ) {
321331 // Ignore undefined symbols that are imported as weak.
322332#if DYLINK_DEBUG
323333 dbg ( 'ignoring undefined weak symbol:' , symName ) ;
324334#endif
335+ entry . value = { { { to64 ( 0 ) } } } ;
325336 continue ;
326337 }
327338#if ASSERTIONS
@@ -343,7 +354,7 @@ var LibraryDylink = {
343354 entry . value = value ;
344355#endif
345356 } else {
346- throw new Error ( `bad export type for '${ symName } ': ${ typeof value } ` ) ;
357+ throw new Error ( `bad export type for '${ symName } ': ${ typeof value } ( ${ value } ) ` ) ;
347358 }
348359 }
349360 }
@@ -390,7 +401,7 @@ var LibraryDylink = {
390401 // Allocate memory even if malloc isn't ready yet. The allocated memory here
391402 // must be zero initialized since its used for all static data, including bss.
392403 $getMemory__noleakcheck: true ,
393- $getMemory__deps : [ '$GOT' , '__heap_base' , '$alignMemory' , 'calloc' ] ,
404+ $getMemory__deps : [ '$GOT' , 'emscripten_get_sbrk_ptr' , ' __heap_base', '$alignMemory' , 'calloc' ] ,
394405 $getMemory : ( size ) => {
395406 // After the runtime is initialized, we must only use sbrk() normally.
396407#if DYLINK_DEBUG
@@ -409,7 +420,14 @@ var LibraryDylink = {
409420 assert ( end <= HEAP8 . length , 'failure to getMemory - memory growth etc. is not supported there, call malloc/sbrk directly or increase INITIAL_MEMORY' ) ;
410421#endif
411422 ___heap_base = end ;
412- GOT [ '__heap_base' ] . value = { { { to64 ( 'end' ) } } } ;
423+ #if PTHREADS
424+ if ( ! ENVIRONMENT_IS_PTHREAD ) {
425+ #endif
426+ var sbrk_ptr = _emscripten_get_sbrk_ptr ( ) ;
427+ { { { makeSetValue ( 'sbrk_ptr' , 0 , 'end' , '*' ) } } }
428+ #if PTHREADS
429+ }
430+ #endif
413431 return ret ;
414432 } ,
415433
@@ -622,7 +640,7 @@ var LibraryDylink = {
622640 * @param {number=} handle
623641 */` ,
624642 $loadWebAssemblyModule__deps : [
625- '$loadDynamicLibrary' , '$getMemory' ,
643+ '$loadDynamicLibrary' , '$getMemory' , '$updateGOT' ,
626644 '$relocateExports' , '$resolveGlobalSymbol' , '$GOTHandler' ,
627645 '$getDylinkMetadata' , '$alignMemory' ,
628646 '$currentModuleWeakSymbols' ,
@@ -632,7 +650,7 @@ var LibraryDylink = {
632650 ] ,
633651 $loadWebAssemblyModule : ( binary , flags , libName , localScope , handle ) = > {
634652#if DYLINK_DEBUG
635- dbg ( 'loadWebAssemblyModule:' , libName ) ;
653+ dbg ( 'loadWebAssemblyModule:' , libName, handle ) ;
636654#endif
637655 var metadata = getDylinkMetadata ( binary ) ;
638656
@@ -651,6 +669,9 @@ var LibraryDylink = {
651669 // exclusive access to it for the duration of this function. See the
652670 // locking in `dynlink.c`.
653671 var firstLoad = ! handle || ! { { { makeGetValue ( 'handle' , C_STRUCTS . dso . mem_allocated , 'i8' ) } } } ;
672+ #if DYLINK_DEBUG
673+ dbg ( 'firstLoad :', firstLoad ) ;
674+ #endif
654675 if ( firstLoad ) {
655676#endif
656677 // alignments are powers of 2
@@ -787,6 +808,7 @@ var LibraryDylink = {
787808 // add new entries to functionsInTableMap
788809 updateTableMap ( tableBase , metadata . tableSize ) ;
789810 moduleExports = relocateExports ( instance . exports , memoryBase ) ;
811+ updateGOT ( moduleExports ) ;
790812#if ASYNCIFY
791813 moduleExports = Asyncify . instrumentWasmExports ( moduleExports ) ;
792814#endif
@@ -878,18 +900,27 @@ var LibraryDylink = {
878900 if ( applyRelocs ) {
879901 if ( runtimeInitialized ) {
880902#if DYLINK_DEBUG
881- dbg ( 'applyRelocs ' ) ;
903+ dbg ( 'running __wasm_apply_data_relocs ' ) ;
882904#endif
883905 applyRelocs ( ) ;
884906 } else {
907+ #if DYLINK_DEBUG
908+ dbg ( 'delaying __wasm_apply_data_relocs' ) ;
909+ #endif
885910 __RELOC_FUNCS__ . push ( applyRelocs ) ;
886911 }
887912 }
888913 var init = moduleExports [ '__wasm_call_ctors' ] ;
889914 if ( init ) {
890915 if ( runtimeInitialized ) {
916+ #if DYLINK_DEBUG
917+ dbg ( 'running __wasm_call_ctors' ) ;
918+ #endif
891919 init ( ) ;
892920 } else {
921+ #if DYLINK_DEBUG
922+ dbg ( 'delaying __wasm_call_ctors' ) ;
923+ #endif
893924 // we aren't ready to run compiled code yet
894925 addOnPostCtor ( init ) ;
895926 }
0 commit comments