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
13+ { { { 
14+ const  UNDEFINED_ADDR  =  to64 ( - 1 ) ; 
15+ } } } 
16+ 
1317var  LibraryDylink  =  { 
1418#if FILESYSTEM 
1519  $registerWasmPlugin__deps : [ '$preloadPlugins' ] , 
@@ -170,10 +174,10 @@ var LibraryDylink = {
170174    get ( obj ,  symName )  { 
171175      var  rtn  =  GOT [ symName ] ; 
172176      if  ( ! rtn )  { 
173-         rtn  =  GOT [ symName ]  =  new  WebAssembly . Global ( { 'value' : '{{{ POINTER_WASM_TYPE }}}' ,  'mutable' : true } ) ; 
174177#if DYLINK_DEBUG  ==  2 
175-         dbg ( " new GOT entry: "   +   symName ) ; 
178+         dbg ( ` new GOT entry: ${ symName } ` ) ; 
176179#endif
180+         rtn  =  GOT [ symName ]  =  new  WebAssembly . Global ( { 'value' : '{{{ POINTER_WASM_TYPE }}}' ,  'mutable' : true } ,  { { {  UNDEFINED_ADDR  } } } ) ; 
177181      } 
178182      if  ( ! currentModuleWeakSymbols . has ( symName ) )  { 
179183        // Any non-weak reference to a symbol marks it as `required`, which 
@@ -189,6 +193,11 @@ var LibraryDylink = {
189193  $isInternalSym : ( symName )  =>  { 
190194    // TODO: find a way to mark these in the binary or avoid exporting them. 
191195    return  [ 
196+       'memory' , 
197+       '__memory_base' , 
198+       '__table_base' , 
199+       '__stack_pointer' , 
200+       '__indirect_function_table' , 
192201      '__cpp_exception' , 
193202      '__c_longjmp' , 
194203      '__wasm_apply_data_relocs' , 
@@ -213,6 +222,7 @@ var LibraryDylink = {
213222
214223  $updateGOT__internal : true , 
215224  $updateGOT__deps : [ '$GOT' ,  '$isInternalSym' ,  '$addFunction' ] , 
225+   $updateGOT__docs : '/** @param {boolean=} replace */' , 
216226  $updateGOT : ( exports ,  replace )  =>  { 
217227#if DYLINK_DEBUG 
218228    dbg ( `updateGOT: adding ${ Object . keys ( exports ) . length }   symbols` ) ; 
@@ -230,8 +240,7 @@ var LibraryDylink = {
230240      } 
231241#endif
232242
233- 
234-       var  existingEntry  =  GOT [ symName ]  &&  GOT [ symName ] . value  !=  0 ; 
243+       var  existingEntry  =  GOT [ symName ]  &&  GOT [ symName ] . value  !=  { { {  UNDEFINED_ADDR  } } } ; 
235244      if  ( replace  ||  ! existingEntry )  { 
236245#if DYLINK_DEBUG  ==  2 
237246        dbg ( `updateGOT: before: ${ symName }   : ${ GOT [ symName ] ?. value }  ` ) ; 
@@ -252,7 +261,7 @@ var LibraryDylink = {
252261#if DYLINK_DEBUG  ==  2 
253262        dbg ( `updateGOT:  after: ${ symName }   : ${ newValue }   (${ value }  )` ) ; 
254263#endif
255-         GOT [ symName ]  || =  new  WebAssembly . Global ( { 'value' : '{{{ POINTER_WASM_TYPE }}}' ,  'mutable' : true } ) ; 
264+         GOT [ symName ]  ?? =  new  WebAssembly . Global ( { 'value' : '{{{ POINTER_WASM_TYPE }}}' ,  'mutable' : true } ) ; 
256265        GOT [ symName ] . value  =  newValue ; 
257266      } 
258267#if DYLINK_DEBUG 
@@ -280,9 +289,12 @@ var LibraryDylink = {
280289
281290  // Applies relocations to exported things. 
282291  $relocateExports__internal : true , 
283-   $relocateExports__deps : [ '$updateGOT' ,  '$isImmutableGlobal' ] , 
284-   $relocateExports__docs : '/** @param {boolean=} replace */' , 
285-   $relocateExports : ( exports ,  memoryBase ,  replace )  = >  { 
292+   $relocateExports__deps : [ '$isImmutableGlobal' ] , 
293+   $relocateExports : ( exports ,  memoryBase  =  0 )  = >  { 
294+ #if DYLINK_DEBUG 
295+     dbg ( `relocateExports memoryBase=${ memoryBase }   count=${ Object . keys ( exports ) . length }  ` ) ; 
296+ #endif
297+ 
286298    function  relocateExport ( name ,  value )  { 
287299#if SPLIT_MODULE 
288300      // Do not modify exports synthesized by wasm-split 
@@ -304,7 +316,6 @@ var LibraryDylink = {
304316    for  ( var  e  in  exports )  { 
305317      relocated [ e ]  =  relocateExport ( e ,  exports [ e ] ) 
306318    } 
307-     updateGOT ( relocated ,  replace ) ; 
308319    return  relocated ; 
309320  } , 
310321
@@ -315,13 +326,17 @@ var LibraryDylink = {
315326    dbg ( 'reportUndefinedSymbols' ) ; 
316327#endif
317328    for  ( var  [ symName ,  entry ]  of  Object . entries ( GOT ) )  { 
318-       if  ( entry . value  ==  0 )  { 
329+       if  ( entry . value  ==  { { {  UNDEFINED_ADDR  } } } )  { 
330+ #if DYLINK_DEBUG 
331+         dbg ( `undef GOT entry: ${ symName }  ` ) ; 
332+ #endif
319333        var  value  =  resolveGlobalSymbol ( symName ,  true ) . sym ; 
320334        if  ( ! value  &&  ! entry . required )  { 
321335          // Ignore undefined symbols that are imported as weak. 
322336#if DYLINK_DEBUG 
323337          dbg ( 'ignoring undefined weak symbol:' ,  symName ) ; 
324338#endif
339+           entry . value  =  { { {  to64 ( 0 )  } } } ; 
325340          continue ; 
326341        } 
327342#if ASSERTIONS 
@@ -343,7 +358,7 @@ var LibraryDylink = {
343358          entry . value  =  value ; 
344359#endif
345360        }  else  { 
346-           throw  new  Error ( `bad export type for '${ symName }  ': ${ typeof  value }  ` ) ; 
361+           throw  new  Error ( `bad export type for '${ symName }  ': ${ typeof  value }  ( ${ value } ) ` ) ; 
347362        } 
348363      } 
349364    } 
@@ -390,7 +405,7 @@ var LibraryDylink = {
390405  // Allocate memory even if malloc isn't ready yet.  The allocated memory here 
391406  // must be zero initialized since its used for all static data, including bss. 
392407  $getMemory__noleakcheck: true , 
393-   $getMemory__deps : [ '$GOT' ,  '__heap_base' ,  '$alignMemory' ,  'calloc' ] , 
408+   $getMemory__deps : [ '$GOT' ,  'emscripten_get_sbrk_ptr'  ,   ' __heap_base',  '$alignMemory' ,  'calloc' ] , 
394409  $getMemory : ( size )  =>  { 
395410    // After the runtime is initialized, we must only use sbrk() normally. 
396411#if DYLINK_DEBUG 
@@ -409,7 +424,25 @@ var LibraryDylink = {
409424    assert ( end  <=  HEAP8 . length ,  'failure to getMemory - memory growth etc. is not supported there, call malloc/sbrk directly or increase INITIAL_MEMORY' ) ; 
410425#endif
411426    ___heap_base  =  end ; 
427+ 
428+     // After allocating the memory from the start of the heap we need to ensure 
429+     // that once the program starts it doesn't use this region.  In relocatable 
430+     // mode we can just update the __heap_base symbol that we are exporting to 
431+     // the main module. 
432+     // When not relocatable `__heap_base` is fixed and exported by the main 
433+     // module, but we can update the `sbrk_ptr` value instead. 
434+ #if RELOCATABLE 
412435    GOT [ '__heap_base' ] . value  =  { { {  to64 ( 'end' )  } } } ; 
436+ #else
437+ #if PTHREADS 
438+     if  ( ! ENVIRONMENT_IS_PTHREAD )  { 
439+ #endif
440+       var  sbrk_ptr  =  _emscripten_get_sbrk_ptr ( ) ; 
441+       { { {  makeSetValue ( 'sbrk_ptr' ,  0 ,  'end' ,  '*' )  } } } 
442+ #if PTHREADS 
443+     } 
444+ #endif
445+ #endif
413446    return  ret ; 
414447  } , 
415448
@@ -622,7 +655,7 @@ var LibraryDylink = {
622655    * @param {number=} handle 
623656    */` , 
624657  $loadWebAssemblyModule__deps : [ 
625-     '$loadDynamicLibrary' ,  '$getMemory' , 
658+     '$loadDynamicLibrary' ,  '$getMemory' ,   '$updateGOT' , 
626659    '$relocateExports' ,  '$resolveGlobalSymbol' ,  '$GOTHandler' , 
627660    '$getDylinkMetadata' ,  '$alignMemory' , 
628661    '$currentModuleWeakSymbols' , 
@@ -632,7 +665,7 @@ var LibraryDylink = {
632665  ] , 
633666  $loadWebAssemblyModule : ( binary ,  flags ,  libName ,  localScope ,  handle )  = >  { 
634667#if DYLINK_DEBUG 
635-     dbg ( 'loadWebAssemblyModule:' ,  libName ) ; 
668+     dbg ( 'loadWebAssemblyModule:' ,  libName,   handle ) ; 
636669#endif
637670    var  metadata =  getDylinkMetadata ( binary ) ; 
638671
@@ -651,6 +684,9 @@ var LibraryDylink = {
651684      // exclusive access to it for the duration of this function.  See the 
652685      // locking in `dynlink.c`. 
653686      var  firstLoad  =  ! handle  ||  ! { { {  makeGetValue ( 'handle' ,  C_STRUCTS . dso . mem_allocated ,  'i8' )  } } } ; 
687+ #if DYLINK_DEBUG 
688+       dbg ( 'firstLoad :',  firstLoad ) ; 
689+ #endif
654690      if  ( firstLoad )  { 
655691#endif
656692        // alignments are powers of 2 
@@ -787,6 +823,7 @@ var LibraryDylink = {
787823        // add new entries to functionsInTableMap 
788824        updateTableMap ( tableBase ,  metadata . tableSize ) ; 
789825        moduleExports  =  relocateExports ( instance . exports ,  memoryBase ) ; 
826+         updateGOT ( moduleExports ) ; 
790827#if ASYNCIFY 
791828        moduleExports  =  Asyncify . instrumentWasmExports ( moduleExports ) ; 
792829#endif
@@ -878,18 +915,27 @@ var LibraryDylink = {
878915          if  ( applyRelocs )  { 
879916            if  ( runtimeInitialized )  { 
880917#if DYLINK_DEBUG 
881-               dbg ( 'applyRelocs ' ) ; 
918+               dbg ( 'running __wasm_apply_data_relocs ' ) ; 
882919#endif
883920              applyRelocs ( ) ; 
884921            }  else  { 
922+ #if DYLINK_DEBUG 
923+               dbg ( 'delaying __wasm_apply_data_relocs' ) ; 
924+ #endif
885925              __RELOC_FUNCS__ . push ( applyRelocs ) ; 
886926            } 
887927          } 
888928          var  init  =  moduleExports [ '__wasm_call_ctors' ] ; 
889929          if  ( init )  { 
890930            if  ( runtimeInitialized )  { 
931+ #if DYLINK_DEBUG 
932+               dbg ( 'running __wasm_call_ctors' ) ; 
933+ #endif
891934              init ( ) ; 
892935            }  else  { 
936+ #if DYLINK_DEBUG 
937+               dbg ( 'delaying __wasm_call_ctors' ) ; 
938+ #endif
893939              // we aren't ready to run compiled code yet 
894940              addOnPostCtor ( init ) ; 
895941            } 
0 commit comments