@@ -352,36 +352,13 @@ class MachOPlatformRuntimeState {
352
352
Error requestPushSymbols (JITDylibState &JDS,
353
353
span<std::pair<std::string_view, bool >> Symbols);
354
354
355
- // / Visits the symbol table for the JITDylib associated with DSOHandle.
356
- // / Visitor should be callable as
357
- // /
358
- // / void (size_t,
359
- // / std::optional<std::pair<ExecutorAddr, MachOExecutorSymbolFlags>>)
360
- // /
361
- // / The visitor function will be called for each element of the Symbols, but
362
- // / in an arbitrary order. The first argument of the callback will indicate
363
- // / the index of the result. The second argument will be std::nullopt (if the
364
- // / symbol at the given index was not present in the symbol table), or a
365
- // / pair containing the symbol's address and flags.
366
- // /
367
- // / This function will remove all elements of Symbols that are found, leaving
368
- // / only the symbols that were not. This allows it to dovetail with
369
- // / requestPushSymbols, enabling the following idiom:
370
- // /
371
- // / ...
372
- // / visitSymbolAddrs(DSO, Symbols);
373
- // / if (!Symbols.empty()) {
374
- // / requestPushSymbols(DSO, Symbols);
375
- // / visitSymbolAddrs(DSO, Symbols);
376
- // / for (auto &Sym : Symbols) {
377
- // / -- handle symbols that were not found --
378
- // / }
379
- // / }
380
- // /
381
- template <typename VisitorFn>
382
- void visitSymbolAddrs (JITDylibState &JDS,
383
- std::vector<std::pair<std::string_view, bool >> &Symbols,
384
- VisitorFn &&Visit);
355
+ // / Attempts to look up the given symbols locally, requesting a push from the
356
+ // / remote if they're not found. Results are written to the Result span, which
357
+ // / must have the same size as the Symbols span.
358
+ Error
359
+ lookupSymbols (JITDylibState &JDS, std::unique_lock<std::mutex> &JDStatesLock,
360
+ span<std::pair<ExecutorAddr, MachOExecutorSymbolFlags>> Result,
361
+ span<std::pair<std::string_view, bool >> Symbols);
385
362
386
363
bool lookupUnwindSections (void *Addr, unw_dynamic_unwind_sections &Info);
387
364
@@ -839,43 +816,16 @@ void *MachOPlatformRuntimeState::dlsym(void *DSOHandle, const char *Symbol) {
839
816
return nullptr ;
840
817
}
841
818
842
- std::string MangledName (" _" );
843
- MangledName += Symbol;
844
- std::vector<std::pair<std::string_view, bool >> Symbols;
845
- Symbols.push_back ({MangledName, false });
819
+ std::string MangledName = std::string (" _" ) + Symbol;
820
+ std::pair<std::string_view, bool > Lookup (MangledName, false );
821
+ std::pair<ExecutorAddr, MachOExecutorSymbolFlags> Result;
846
822
847
- ExecutorAddr Result;
848
- using ElemResult =
849
- std::optional<std::pair<ExecutorAddr, MachOExecutorSymbolFlags>>;
850
-
851
- // Try to resolve the symbol in the local symbol tables.
852
- visitSymbolAddrs (*JDS, Symbols, [&](size_t Idx, ElemResult E) {
853
- if (E)
854
- Result = E->first ;
855
- });
856
-
857
- // Return early if we found it.
858
- if (Symbols.empty ())
859
- return Result.toPtr <void *>();
860
-
861
- // Otherwise call back to the controller to try to request that the symbol
862
- // be materialized.
863
- Lock.unlock ();
864
- if (auto Err = requestPushSymbols (*JDS, {Symbols.data (), Symbols.size ()})) {
823
+ if (auto Err = lookupSymbols (*JDS, Lock, {&Result, 1 }, {&Lookup, 1 })) {
865
824
DLFcnError = toString (std::move (Err));
866
825
return nullptr ;
867
826
}
868
- Lock.lock ();
869
-
870
- // Try another local resolution.
871
- visitSymbolAddrs (*JDS, Symbols, [&](size_t Idx, ElemResult E) {
872
- if (E)
873
- Result = E->first ;
874
- });
875
827
876
- // At this point Result has either been set (if we found the symbol) or is
877
- // still null (if we didn't). Either way it's the right value.
878
- return Result.toPtr <void *>();
828
+ return Result.first .toPtr <void *>();
879
829
}
880
830
881
831
int MachOPlatformRuntimeState::registerAtExit (void (*F)(void *), void *Arg,
@@ -967,22 +917,69 @@ Error MachOPlatformRuntimeState::requestPushSymbols(
967
917
return OpErr;
968
918
}
969
919
970
- template <typename VisitorFn>
971
- void MachOPlatformRuntimeState::visitSymbolAddrs (
972
- JITDylibState &JDS, std::vector<std::pair<std::string_view, bool >> &Symbols,
973
- VisitorFn &&Visit) {
974
-
975
- std::vector<std::pair<std::string_view, bool >> RemainingSymbols;
976
-
920
+ Error MachOPlatformRuntimeState::lookupSymbols (
921
+ JITDylibState &JDS, std::unique_lock<std::mutex> &JDStatesLock,
922
+ span<std::pair<ExecutorAddr, MachOExecutorSymbolFlags>> Result,
923
+ span<std::pair<std::string_view, bool >> Symbols) {
924
+ assert (JDStatesLock.owns_lock () &&
925
+ " JDStatesLock should be locked at call-site" );
926
+ assert (Result.size () == Symbols.size () &&
927
+ " Results and Symbols span sizes should match" );
928
+
929
+ // Make an initial pass over the local symbol table.
930
+ std::vector<size_t > MissingSymbolIndexes;
977
931
for (size_t Idx = 0 ; Idx != Symbols.size (); ++Idx) {
978
932
auto I = JDS.SymbolTable .find (Symbols[Idx].first );
979
933
if (I != JDS.SymbolTable .end ())
980
- Visit ( Idx, I->second ) ;
934
+ Result[ Idx] = I->second ;
981
935
else
982
- RemainingSymbols .push_back (Symbols[ Idx] );
936
+ MissingSymbolIndexes .push_back (Idx);
983
937
}
984
938
985
- Symbols = std::move (RemainingSymbols);
939
+ // If everything has been resolved already then bail out early.
940
+ if (MissingSymbolIndexes.empty ())
941
+ return Error::success ();
942
+
943
+ // Otherwise call back to the controller to try to request that the symbol
944
+ // be materialized.
945
+ std::vector<std::pair<std::string_view, bool >> MissingSymbols;
946
+ MissingSymbols.reserve (MissingSymbolIndexes.size ());
947
+ printdbg (" requesting push of %i missing symbols...\n " ,
948
+ MissingSymbolIndexes.size ());
949
+ for (auto MissingIdx : MissingSymbolIndexes)
950
+ MissingSymbols.push_back (Symbols[MissingIdx]);
951
+
952
+ JDStatesLock.unlock ();
953
+ if (auto Err = requestPushSymbols (
954
+ JDS, {MissingSymbols.data (), MissingSymbols.size ()}))
955
+ return Err;
956
+ JDStatesLock.lock ();
957
+
958
+ // Try to resolve the previously missing symbols locally.
959
+ std::vector<size_t > MissingRequiredSymbols;
960
+ for (auto MissingIdx : MissingSymbolIndexes) {
961
+ auto I = JDS.SymbolTable .find (Symbols[MissingIdx].first );
962
+ if (I != JDS.SymbolTable .end ())
963
+ Result[MissingIdx] = I->second ;
964
+ else {
965
+ if (Symbols[MissingIdx].second )
966
+ MissingRequiredSymbols.push_back (MissingIdx);
967
+ else
968
+ Result[MissingIdx] = {ExecutorAddr (), {}};
969
+ }
970
+ }
971
+
972
+ // Error out if any missing symbols could not be resolved.
973
+ if (!MissingRequiredSymbols.empty ()) {
974
+ std::ostringstream ErrStream;
975
+ ErrStream << " Lookup could not find required symbols: [ " ;
976
+ for (auto MissingIdx : MissingRequiredSymbols)
977
+ ErrStream << " \" " << Symbols[MissingIdx].first << " \" " ;
978
+ ErrStream << " ]" ;
979
+ return make_error<StringError>(ErrStream.str ());
980
+ }
981
+
982
+ return Error::success ();
986
983
}
987
984
988
985
// eh-frame registration functions.
0 commit comments