@@ -177,30 +177,50 @@ class JuliaJITEventListener: public JITEventListener
177
177
return linfo;
178
178
}
179
179
180
- virtual void NotifyObjectEmitted (const object::ObjectFile &obj ,
180
+ virtual void NotifyObjectEmitted (const object::ObjectFile &Object ,
181
181
const RuntimeDyld::LoadedObjectInfo &L)
182
182
{
183
- return _NotifyObjectEmitted (obj,obj,L, nullptr );
183
+ return _NotifyObjectEmitted (Object, L, nullptr );
184
184
}
185
185
186
- virtual void _NotifyObjectEmitted (const object::ObjectFile &obj,
187
- const object::ObjectFile &debugObj,
186
+ virtual void _NotifyObjectEmitted (const object::ObjectFile &Object,
188
187
const RuntimeDyld::LoadedObjectInfo &L,
189
188
RTDyldMemoryManager *memmgr)
190
189
{
191
190
jl_ptls_t ptls = jl_get_ptls_states ();
192
191
// This function modify codeinst->fptr in GC safe region.
193
192
// This should be fine since the GC won't scan this field.
194
193
int8_t gc_state = jl_gc_safe_enter (ptls);
194
+
195
+ auto SavedObject = L.getObjectForDebug (Object).takeBinary ();
196
+ // If the debug object is unavailable, save (a copy of) the original object
197
+ // for our backtraces
198
+ if (!SavedObject.first ) {
199
+ // This is unfortunate, but there doesn't seem to be a way to take
200
+ // ownership of the original buffer
201
+ auto NewBuffer = MemoryBuffer::getMemBufferCopy (
202
+ Object.getData (), Object.getFileName ());
203
+ auto NewObj = object::ObjectFile::createObjectFile (NewBuffer->getMemBufferRef ());
204
+ assert (NewObj);
205
+ SavedObject = std::make_pair (std::move (*NewObj), std::move (NewBuffer));
206
+ }
207
+ const object::ObjectFile &debugObj = *SavedObject.first .release ();
208
+ SavedObject.second .release ();
209
+
195
210
object::section_iterator Section = debugObj.section_begin ();
196
211
object::section_iterator EndSection = debugObj.section_end ();
197
212
198
- std::map<StringRef,object::SectionRef,strrefcomp> loadedSections;
199
- for (const object::SectionRef &lSection: obj.sections ()) {
213
+ std::map<StringRef, object::SectionRef, strrefcomp> loadedSections;
214
+ for (const object::SectionRef &lSection: Object.sections ()) {
215
+ #if JL_LLVM_VERSION >= 100000
216
+ auto sName = lSection.getName ();
217
+ if (sName )
218
+ loadedSections[*sName ] = lSection;
219
+ #else
200
220
StringRef sName ;
201
- if (!lSection.getName (sName )) {
221
+ if (!lSection.getName (sName ))
202
222
loadedSections[sName ] = lSection;
203
- }
223
+ # endif
204
224
}
205
225
auto getLoadAddress = [&] (const StringRef &sName ) -> uint64_t {
206
226
auto search = loadedSections.find (sName );
@@ -215,15 +235,21 @@ class JuliaJITEventListener: public JITEventListener
215
235
size_t arm_exidx_len = 0 ;
216
236
uint64_t arm_text_addr = 0 ;
217
237
size_t arm_text_len = 0 ;
218
- for (auto §ion: obj .sections ()) {
238
+ for (auto §ion: Object .sections ()) {
219
239
bool istext = false ;
220
240
if (section.isText ()) {
221
241
istext = true ;
222
242
}
223
243
else {
244
+ #if JL_LLVM_VERSION >= 100000
245
+ auto sName = section.getName ();
246
+ if (!sName )
247
+ continue ;
248
+ #else
224
249
StringRef sName ;
225
250
if (section.getName (sName ))
226
251
continue ;
252
+ #endif
227
253
if (sName != " .ARM.exidx" ) {
228
254
continue ;
229
255
}
@@ -285,8 +311,14 @@ class JuliaJITEventListener: public JITEventListener
285
311
Section = SectionOrError.get ();
286
312
assert (Section != EndSection && Section->isText ());
287
313
SectionAddr = Section->getAddress ();
314
+ #if JL_LLVM_VERSION >= 100000
315
+ auto secName = Section->getName ();
316
+ assert (secName);
317
+ SectionLoadAddr = getLoadAddress (*secName);
318
+ #else
288
319
Section->getName (sName );
289
320
SectionLoadAddr = getLoadAddress (sName );
321
+ #endif
290
322
Addr -= SectionAddr - SectionLoadAddr;
291
323
*pAddr = (uint8_t *)Addr;
292
324
if (SectionAddrCheck)
@@ -342,9 +374,15 @@ class JuliaJITEventListener: public JITEventListener
342
374
if (Section == EndSection) continue ;
343
375
if (!Section->isText ()) continue ;
344
376
uint64_t SectionAddr = Section->getAddress ();
377
+ #if JL_LLVM_VERSION >= 100000
378
+ Expected<StringRef> secName = Section->getName ();
379
+ assert (secName);
380
+ uint64_t SectionLoadAddr = getLoadAddress (*secName);
381
+ #else
345
382
StringRef secName;
346
383
Section->getName (secName);
347
384
uint64_t SectionLoadAddr = getLoadAddress (secName);
385
+ #endif
348
386
Addr -= SectionAddr - SectionLoadAddr;
349
387
auto sNameOrError = sym_iter.getName ();
350
388
assert (sNameOrError );
@@ -373,7 +411,7 @@ class JuliaJITEventListener: public JITEventListener
373
411
ObjectInfo tmp = {&debugObj,
374
412
(size_t )SectionSize,
375
413
(ptrdiff_t )(SectionAddr - SectionLoadAddr),
376
- DWARFContext::create (debugObj, &L ).release (),
414
+ DWARFContext::create (debugObj).release (),
377
415
};
378
416
objectmap[SectionLoadAddr] = tmp;
379
417
first = false ;
@@ -384,7 +422,7 @@ class JuliaJITEventListener: public JITEventListener
384
422
}
385
423
386
424
// must implement if we ever start freeing code
387
- // virtual void NotifyFreeingObject(const ObjectImage &obj ) {}
425
+ // virtual void NotifyFreeingObject(const ObjectImage &Object ) {}
388
426
// virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {}
389
427
390
428
std::map<size_t , ObjectInfo, revcomp>& getObjectMap ()
@@ -395,12 +433,11 @@ class JuliaJITEventListener: public JITEventListener
395
433
};
396
434
397
435
JL_DLLEXPORT void ORCNotifyObjectEmitted (JITEventListener *Listener,
398
- const object::ObjectFile &obj,
399
- const object::ObjectFile &debugObj,
436
+ const object::ObjectFile &Object,
400
437
const RuntimeDyld::LoadedObjectInfo &L,
401
438
RTDyldMemoryManager *memmgr)
402
439
{
403
- ((JuliaJITEventListener*)Listener)->_NotifyObjectEmitted (obj,debugObj,L, memmgr);
440
+ ((JuliaJITEventListener*)Listener)->_NotifyObjectEmitted (Object, L, memmgr);
404
441
}
405
442
406
443
static std::pair<char *, bool > jl_demangle (const char *name)
@@ -445,12 +482,14 @@ JITEventListener *CreateJuliaJITEventListener()
445
482
// *frames is a one element array containing whatever we could come up
446
483
// with for the current frame. here we'll try to expand it using debug info
447
484
// func_name and file_name are either NULL or malloc'd pointers
448
- static int lookup_pointer (DIContext *context, jl_frame_t **frames,
449
- size_t pointer, int demangle, int noInline)
485
+ static int lookup_pointer (
486
+ const object::ObjectFile *object, DIContext *context,
487
+ jl_frame_t **frames, size_t pointer,
488
+ int demangle, int noInline)
450
489
{
451
490
// This function is not allowed to reference any TLS variables
452
491
// since it can be called from an unmanaged thread on OSX.
453
- if (!context) {
492
+ if (!context || !object ) {
454
493
if (demangle) {
455
494
char *oldname = (*frames)[0 ].func_name ;
456
495
if (oldname != NULL ) {
@@ -473,14 +512,14 @@ static int lookup_pointer(DIContext *context, jl_frame_t **frames,
473
512
DILineInfoSpecifier infoSpec (DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
474
513
DILineInfoSpecifier::FunctionNameKind::ShortName);
475
514
476
- auto inlineInfo = context->getInliningInfoForAddress (makeAddress (pointer), infoSpec);
515
+ auto inlineInfo = context->getInliningInfoForAddress (makeAddress (object, pointer), infoSpec);
477
516
478
517
int fromC = (*frames)[0 ].fromC ;
479
518
int n_frames = inlineInfo.getNumberOfFrames ();
480
519
if (n_frames == 0 ) {
481
520
jl_mutex_unlock_maybe_nogc (&codegen_lock);
482
521
// no line number info available in the context, return without the context
483
- return lookup_pointer (NULL , frames, pointer, demangle, noInline);
522
+ return lookup_pointer (NULL , NULL , frames, pointer, demangle, noInline);
484
523
}
485
524
if (noInline)
486
525
n_frames = 1 ;
@@ -497,7 +536,7 @@ static int lookup_pointer(DIContext *context, jl_frame_t **frames,
497
536
info = inlineInfo.getFrame (i);
498
537
}
499
538
else {
500
- info = context->getLineInfoForAddress (makeAddress (pointer), infoSpec);
539
+ info = context->getLineInfoForAddress (makeAddress (object, pointer), infoSpec);
501
540
}
502
541
503
542
jl_frame_t *frame = &(*frames)[i];
@@ -571,8 +610,14 @@ static debug_link_info getDebuglink(const object::ObjectFile &Obj)
571
610
{
572
611
debug_link_info info = {};
573
612
for (const object::SectionRef &Section: Obj.sections ()) {
613
+ #if JL_LLVM_VERSION >= 100000
614
+ Expected<StringRef> sName = Section.getName ();
615
+ if (sName && *sName == " .gnu_debuglink" )
616
+ #else
574
617
StringRef sName ;
575
- if (!Section.getName (sName ) && sName == " .gnu_debuglink" ) {
618
+ if (!Section.getName (sName ) && sName == " .gnu_debuglink" )
619
+ #endif
620
+ {
576
621
StringRef Contents;
577
622
#if JL_LLVM_VERSION >= 90000
578
623
auto found = Section.getContents ();
@@ -1135,7 +1180,7 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip
1135
1180
}
1136
1181
}
1137
1182
}
1138
- return lookup_pointer (context, frames, pointer + slide, isSysImg, noInline);
1183
+ return lookup_pointer (object, context, frames, pointer + slide, isSysImg, noInline);
1139
1184
}
1140
1185
1141
1186
int jl_DI_for_fptr (uint64_t fptr, uint64_t *symsize, int64_t *slide, int64_t *section_slide,
@@ -1222,12 +1267,12 @@ int jl_getFunctionInfo(jl_frame_t **frames_out, size_t pointer, int skipC, int n
1222
1267
*frames_out = frames;
1223
1268
1224
1269
llvm::DIContext *context;
1225
- const llvm:: object::ObjectFile *object;
1270
+ const object::ObjectFile *object;
1226
1271
uint64_t symsize;
1227
1272
int64_t slide = 0 ;
1228
1273
if (jl_DI_for_fptr (pointer, &symsize, &slide, NULL , &object, &context)) {
1229
1274
frames[0 ].linfo = jl_jit_events->lookupLinfo (pointer);
1230
- int nf = lookup_pointer (context, frames_out, pointer+slide, 1 , noInline);
1275
+ int nf = lookup_pointer (object, context, frames_out, pointer+slide, 1 , noInline);
1231
1276
return nf;
1232
1277
}
1233
1278
return jl_getDylibFunctionInfo (frames_out, pointer, skipC, noInline);
0 commit comments