@@ -716,6 +716,85 @@ static inline void ignoreError(T &err)
716716#endif
717717}
718718
719+ static void get_function_name_and_base (const object::ObjectFile *object, bool insysimage,
720+ void **saddr, char **name, size_t pointer,
721+ int64_t slide)
722+ {
723+ if (!object)
724+ return ;
725+ // Assume we only need base address for sysimg for now
726+ if (!insysimage || !sysimg_fvars)
727+ saddr = nullptr ;
728+ // Try platform specific methods first since they are usually faster
729+ if (saddr && !*saddr) {
730+ #if defined(_OS_LINUX_) && !defined(JL_DISABLE_LIBUNWIND)
731+ unw_proc_info_t pip;
732+ if (unw_get_proc_info_by_ip (unw_local_addr_space, pointer, &pip, NULL ) == 0 ) {
733+ *saddr = (void *)pip.start_ip ;
734+ }
735+ #endif
736+ #if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_)
737+ DWORD64 ImageBase;
738+ PRUNTIME_FUNCTION fn = RtlLookupFunctionEntry (pointer, &ImageBase, NULL );
739+ if (fn) {
740+ *saddr = (void *)(ImageBase + fn->BeginAddress );
741+ }
742+ #endif
743+ }
744+ if ((saddr && !*saddr) || (name && !*name)) {
745+ size_t distance = (size_t )-1 ;
746+ SymRef sym_found;
747+ for (auto sym: object->symbols ()) {
748+ auto addr = sym.getAddress ();
749+ if (!addr)
750+ continue ;
751+ size_t symptr = addr.get ();
752+ if (symptr > pointer + slide)
753+ continue ;
754+ size_t new_dist = pointer + slide - symptr;
755+ if (new_dist > distance)
756+ continue ;
757+ distance = new_dist;
758+ sym_found = sym;
759+ }
760+ if (distance != (size_t )-1 ) {
761+ if (saddr && !*saddr) {
762+ auto addr = sym_found.getAddress ();
763+ assert (addr);
764+ *saddr = (void *)(uintptr_t )(addr.get () - slide);
765+ }
766+ if (name && !*name) {
767+ if (auto name_or_err = sym_found.getName ()) {
768+ auto nameref = name_or_err.get ();
769+ size_t len = nameref.size ();
770+ *name = (char *)malloc (len + 1 );
771+ (*name)[len] = 0 ;
772+ memcpy (*name, nameref.data (), len);
773+ }
774+ }
775+ }
776+ }
777+ #ifdef _OS_WINDOWS_
778+ // For ntdll and msvcrt since we are currently only parsing DWARF debug info through LLVM
779+ if (!insysimage && name && !*name) {
780+ static char frame_info_func[
781+ sizeof (SYMBOL_INFO) +
782+ MAX_SYM_NAME * sizeof (TCHAR)];
783+ DWORD64 dwDisplacement64 = 0 ;
784+ DWORD64 dwAddress = pointer;
785+ PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)frame_info_func;
786+ pSymbol->SizeOfStruct = sizeof (SYMBOL_INFO);
787+ pSymbol->MaxNameLen = MAX_SYM_NAME;
788+ jl_in_stackwalk = 1 ;
789+ if (SymFromAddr (GetCurrentProcess (), dwAddress, &dwDisplacement64, pSymbol)) {
790+ // errors are ignored
791+ jl_copy_str (name, pSymbol->Name );
792+ }
793+ jl_in_stackwalk = 0 ;
794+ }
795+ #endif
796+ }
797+
719798extern " C" void jl_refresh_dbg_module_list (void );
720799bool jl_dylib_DI_for_fptr (size_t pointer, const llvm::object::ObjectFile **obj, llvm::DIContext **context, int64_t *slide, int64_t *section_slide,
721800 bool onlySysImg, bool *isSysImg, void **saddr, char **name, char **filename)
@@ -746,35 +825,12 @@ bool jl_dylib_DI_for_fptr(size_t pointer, const llvm::object::ObjectFile **obj,
746825 if (onlySysImg && !insysimage) {
747826 return false ;
748827 }
749- static char frame_info_func[
750- sizeof (SYMBOL_INFO) +
751- MAX_SYM_NAME * sizeof (TCHAR)];
752- DWORD64 dwDisplacement64 = 0 ;
753- DWORD64 dwAddress = pointer;
754- PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)frame_info_func;
755- pSymbol->SizeOfStruct = sizeof (SYMBOL_INFO);
756- pSymbol->MaxNameLen = MAX_SYM_NAME;
757- jl_in_stackwalk = 1 ;
758- if (SymFromAddr (GetCurrentProcess (), dwAddress, &dwDisplacement64,
759- pSymbol)) {
760- // SymFromAddr returned success
761- // errors are ignored, but are hopefully patched up by
762- // using llvm to read the object (below)
763- if (name)
764- jl_copy_str (name, pSymbol->Name );
765- if (saddr)
766- *saddr = (void *)(uintptr_t )pSymbol->Address ;
767- }
768- else if (saddr) {
769- *saddr = NULL ;
770- }
771-
772828 // If we didn't find the filename before in the debug
773829 // info, use the dll name
774830 if (filename && !*filename)
775831 jl_copy_str (filename, fname.data ());
776-
777- jl_in_stackwalk = 0 ;
832+ if (saddr)
833+ *saddr = NULL ;
778834
779835#else // ifdef _OS_WINDOWS_
780836 Dl_info dlinfo;
@@ -832,6 +888,7 @@ bool jl_dylib_DI_for_fptr(size_t pointer, const llvm::object::ObjectFile **obj,
832888 *context = it->second .ctx ;
833889 *slide = it->second .slide ;
834890 *section_slide = it->second .section_slide ;
891+ get_function_name_and_base (*obj, insysimage, saddr, name, pointer, *slide);
835892 return true ;
836893 }
837894
@@ -961,6 +1018,7 @@ bool jl_dylib_DI_for_fptr(size_t pointer, const llvm::object::ObjectFile **obj,
9611018 // update cache
9621019 objfileentry_t entry = {*obj, *context, *slide, *section_slide};
9631020 objfilemap[fbase] = entry;
1021+ get_function_name_and_base (*obj, insysimage, saddr, name, pointer, *slide);
9641022 return true ;
9651023}
9661024
@@ -999,32 +1057,15 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip
9991057 return 1 ;
10001058 }
10011059 frame0->fromC = !isSysImg;
1002- if (isSysImg && sysimg_fvars) {
1003- #if defined(_OS_LINUX_) && !defined(JL_DISABLE_LIBUNWIND)
1004- unw_proc_info_t pip;
1005- if (!saddr && unw_get_proc_info_by_ip (unw_local_addr_space,
1006- pointer, &pip, NULL ) == 0 )
1007- saddr = (void *)pip.start_ip ;
1008- #endif
1009- #if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_)
1010- if (!saddr) {
1011- DWORD64 ImageBase;
1012- PRUNTIME_FUNCTION fn = RtlLookupFunctionEntry (pointer, &ImageBase, NULL );
1013- if (fn)
1014- saddr = (void *)(ImageBase + fn->BeginAddress );
1015- }
1016- #endif
1017- if (saddr) {
1018- for (size_t i = 0 ; i < sysimg_fvars_n; i++) {
1019- if (saddr == sysimg_fvars[i]) {
1020- frame0->linfo = sysimg_fvars_linfo[i];
1021- break ;
1022- }
1060+ if (isSysImg && sysimg_fvars && saddr) {
1061+ for (size_t i = 0 ; i < sysimg_fvars_n; i++) {
1062+ if (saddr == sysimg_fvars[i]) {
1063+ frame0->linfo = sysimg_fvars_linfo[i];
1064+ break ;
10231065 }
10241066 }
1025- return lookup_pointer (context, frames, pointer+slide, isSysImg, noInline);
10261067 }
1027- return lookup_pointer (context, frames, pointer+ slide, isSysImg, noInline);
1068+ return lookup_pointer (context, frames, pointer + slide, isSysImg, noInline);
10281069}
10291070
10301071int jl_DI_for_fptr (uint64_t fptr, uint64_t *symsize, int64_t *slide, int64_t *section_slide,
0 commit comments