@@ -1026,13 +1026,20 @@ openDebugInfo(StringRef debuginfopath, const debug_link_info &info)
1026
1026
#endif
1027
1027
1028
1028
static uint64_t jl_sysimage_base;
1029
- static void **sysimg_fvars;
1029
+ static const char *sysimg_fvars_base = nullptr ;
1030
+ static const int32_t *sysimg_fvars_offsets;
1030
1031
static jl_method_instance_t **sysimg_fvars_linfo;
1031
1032
static size_t sysimg_fvars_n;
1032
- extern " C" void jl_register_fptrs (uint64_t sysimage_base, void **fptrs, jl_method_instance_t **linfos, size_t n)
1033
+ static const void *sysimg_fvars (size_t idx)
1034
+ {
1035
+ return sysimg_fvars_base + sysimg_fvars_offsets[idx];
1036
+ }
1037
+ void jl_register_fptrs (uint64_t sysimage_base, const char *base, const int32_t *offsets,
1038
+ jl_method_instance_t **linfos, size_t n)
1033
1039
{
1034
1040
jl_sysimage_base = (uintptr_t )sysimage_base;
1035
- sysimg_fvars = fptrs;
1041
+ sysimg_fvars_base = base;
1042
+ sysimg_fvars_offsets = offsets;
1036
1043
sysimg_fvars_linfo = linfos;
1037
1044
sysimg_fvars_n = n;
1038
1045
}
@@ -1046,6 +1053,85 @@ static inline void ignoreError(T &err)
1046
1053
#endif
1047
1054
}
1048
1055
1056
+ static void get_function_name_and_base (const object::ObjectFile *object, bool insysimage,
1057
+ void **saddr, char **name, size_t pointer,
1058
+ int64_t slide)
1059
+ {
1060
+ if (!object)
1061
+ return ;
1062
+ // Assume we only need base address for sysimg for now
1063
+ if (!insysimage || !sysimg_fvars_base)
1064
+ saddr = nullptr ;
1065
+ // Try platform specific methods first since they are usually faster
1066
+ if (saddr && !*saddr) {
1067
+ #if defined(_OS_LINUX_) && !defined(JL_DISABLE_LIBUNWIND)
1068
+ unw_proc_info_t pip;
1069
+ if (unw_get_proc_info_by_ip (unw_local_addr_space, pointer, &pip, NULL ) == 0 ) {
1070
+ *saddr = (void *)pip.start_ip ;
1071
+ }
1072
+ #endif
1073
+ #if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_)
1074
+ DWORD64 ImageBase;
1075
+ PRUNTIME_FUNCTION fn = RtlLookupFunctionEntry (pointer, &ImageBase, NULL );
1076
+ if (fn) {
1077
+ *saddr = (void *)(ImageBase + fn->BeginAddress );
1078
+ }
1079
+ #endif
1080
+ }
1081
+ if ((saddr && !*saddr) || (name && !*name)) {
1082
+ size_t distance = (size_t )-1 ;
1083
+ SymRef sym_found;
1084
+ for (auto sym: object->symbols ()) {
1085
+ auto addr = sym.getAddress ();
1086
+ if (!addr)
1087
+ continue ;
1088
+ size_t symptr = addr.get ();
1089
+ if (symptr > pointer + slide)
1090
+ continue ;
1091
+ size_t new_dist = pointer + slide - symptr;
1092
+ if (new_dist > distance)
1093
+ continue ;
1094
+ distance = new_dist;
1095
+ sym_found = sym;
1096
+ }
1097
+ if (distance != (size_t )-1 ) {
1098
+ if (saddr && !*saddr) {
1099
+ auto addr = sym_found.getAddress ();
1100
+ assert (addr);
1101
+ *saddr = (void *)(uintptr_t )(addr.get () - slide);
1102
+ }
1103
+ if (name && !*name) {
1104
+ if (auto name_or_err = sym_found.getName ()) {
1105
+ auto nameref = name_or_err.get ();
1106
+ size_t len = nameref.size ();
1107
+ *name = (char *)malloc (len + 1 );
1108
+ (*name)[len] = 0 ;
1109
+ memcpy (*name, nameref.data (), len);
1110
+ }
1111
+ }
1112
+ }
1113
+ }
1114
+ #ifdef _OS_WINDOWS_
1115
+ // For ntdll and msvcrt since we are currently only parsing DWARF debug info through LLVM
1116
+ if (!insysimage && name && !*name) {
1117
+ static char frame_info_func[
1118
+ sizeof (SYMBOL_INFO) +
1119
+ MAX_SYM_NAME * sizeof (TCHAR)];
1120
+ DWORD64 dwDisplacement64 = 0 ;
1121
+ DWORD64 dwAddress = pointer;
1122
+ PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)frame_info_func;
1123
+ pSymbol->SizeOfStruct = sizeof (SYMBOL_INFO);
1124
+ pSymbol->MaxNameLen = MAX_SYM_NAME;
1125
+ jl_in_stackwalk = 1 ;
1126
+ if (SymFromAddr (GetCurrentProcess (), dwAddress, &dwDisplacement64, pSymbol)) {
1127
+ // errors are ignored
1128
+ jl_copy_str (name, pSymbol->Name );
1129
+ }
1130
+ jl_in_stackwalk = 0 ;
1131
+ }
1132
+ #endif
1133
+ }
1134
+
1049
1135
extern " C" void jl_refresh_dbg_module_list (void );
1050
1136
bool jl_dylib_DI_for_fptr (size_t pointer, const llvm::object::ObjectFile **obj, llvm::DIContext **context, int64_t *slide, int64_t *section_slide,
1051
1137
bool onlySysImg, bool *isSysImg, void **saddr, char **name, char **filename)
@@ -1076,35 +1162,12 @@ bool jl_dylib_DI_for_fptr(size_t pointer, const llvm::object::ObjectFile **obj,
1076
1162
if (onlySysImg && !insysimage) {
1077
1163
return false ;
1078
1164
}
1079
- static char frame_info_func[
1080
- sizeof (SYMBOL_INFO) +
1081
- MAX_SYM_NAME * sizeof (TCHAR)];
1082
- DWORD64 dwDisplacement64 = 0 ;
1083
- DWORD64 dwAddress = pointer;
1084
- PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)frame_info_func;
1085
- pSymbol->SizeOfStruct = sizeof (SYMBOL_INFO);
1086
- pSymbol->MaxNameLen = MAX_SYM_NAME;
1087
- jl_in_stackwalk = 1 ;
1088
- if (SymFromAddr (GetCurrentProcess (), dwAddress, &dwDisplacement64,
1089
- pSymbol)) {
1090
- // SymFromAddr returned success
1091
- // errors are ignored, but are hopefully patched up by
1092
- // using llvm to read the object (below)
1093
- if (name)
1094
- jl_copy_str (name, pSymbol->Name );
1095
- if (saddr)
1096
- *saddr = (void *)(uintptr_t )pSymbol->Address ;
1097
- }
1098
- else if (saddr) {
1099
- *saddr = NULL ;
1100
- }
1101
-
1102
1165
// If we didn't find the filename before in the debug
1103
1166
// info, use the dll name
1104
1167
if (filename && !*filename)
1105
1168
jl_copy_str (filename, fname.data ());
1106
-
1107
- jl_in_stackwalk = 0 ;
1169
+ if (saddr)
1170
+ *saddr = NULL ;
1108
1171
1109
1172
#else // ifdef _OS_WINDOWS_
1110
1173
Dl_info dlinfo;
@@ -1168,6 +1231,7 @@ bool jl_dylib_DI_for_fptr(size_t pointer, const llvm::object::ObjectFile **obj,
1168
1231
*context = it->second .ctx ;
1169
1232
*slide = it->second .slide ;
1170
1233
*section_slide = it->second .section_slide ;
1234
+ get_function_name_and_base (*obj, insysimage, saddr, name, pointer, *slide);
1171
1235
return true ;
1172
1236
}
1173
1237
@@ -1361,6 +1425,7 @@ bool jl_dylib_DI_for_fptr(size_t pointer, const llvm::object::ObjectFile **obj,
1361
1425
// update cache
1362
1426
objfileentry_t entry = {*obj, *context, *slide, *section_slide};
1363
1427
objfilemap[fbase] = entry;
1428
+ get_function_name_and_base (*obj, insysimage, saddr, name, pointer, *slide);
1364
1429
return true ;
1365
1430
}
1366
1431
@@ -1399,32 +1464,15 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip
1399
1464
return 1 ;
1400
1465
}
1401
1466
frame0->fromC = !isSysImg;
1402
- if (isSysImg && sysimg_fvars) {
1403
- #ifdef _OS_LINUX_
1404
- unw_proc_info_t pip;
1405
- if (!saddr && unw_get_proc_info_by_ip (unw_local_addr_space,
1406
- pointer, &pip, NULL ) == 0 )
1407
- saddr = (void *)pip.start_ip ;
1408
- #endif
1409
- #if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_)
1410
- if (!saddr) {
1411
- DWORD64 ImageBase;
1412
- PRUNTIME_FUNCTION fn = RtlLookupFunctionEntry (pointer, &ImageBase, NULL );
1413
- if (fn)
1414
- saddr = (void *)(ImageBase + fn->BeginAddress );
1415
- }
1416
- #endif
1417
- if (saddr) {
1418
- for (size_t i = 0 ; i < sysimg_fvars_n; i++) {
1419
- if (saddr == sysimg_fvars[i]) {
1420
- frame0->linfo = sysimg_fvars_linfo[i];
1421
- break ;
1422
- }
1467
+ if (isSysImg && sysimg_fvars_base && saddr) {
1468
+ for (size_t i = 0 ; i < sysimg_fvars_n; i++) {
1469
+ if (saddr == sysimg_fvars (i)) {
1470
+ frame0->linfo = sysimg_fvars_linfo[i];
1471
+ break ;
1423
1472
}
1424
1473
}
1425
- return lookup_pointer (context, frames, pointer+slide, isSysImg, noInline);
1426
1474
}
1427
- return lookup_pointer (context, frames, pointer+ slide, isSysImg, noInline);
1475
+ return lookup_pointer (context, frames, pointer + slide, isSysImg, noInline);
1428
1476
}
1429
1477
1430
1478
int jl_DI_for_fptr (uint64_t fptr, uint64_t *symsize, int64_t *slide, int64_t *section_slide,
0 commit comments