@@ -119,10 +119,9 @@ Error EHFrameSplitter::processBlock(LinkGraph &G, Block &B,
119
119
}
120
120
121
121
EHFrameEdgeFixer::EHFrameEdgeFixer (StringRef EHFrameSectionName,
122
- unsigned PointerSize, Edge::Kind Delta64,
123
- Edge::Kind Delta32, Edge::Kind NegDelta32)
124
- : EHFrameSectionName(EHFrameSectionName), PointerSize(PointerSize),
125
- Delta64 (Delta64), Delta32(Delta32), NegDelta32(NegDelta32) {}
122
+ Edge::Kind Delta64, Edge::Kind NegDelta32)
123
+ : EHFrameSectionName(EHFrameSectionName), Delta64(Delta64),
124
+ NegDelta32 (NegDelta32) {}
126
125
127
126
Error EHFrameEdgeFixer::operator ()(LinkGraph &G) {
128
127
auto *EHFrame = G.findSectionByName (EHFrameSectionName);
@@ -135,11 +134,6 @@ Error EHFrameEdgeFixer::operator()(LinkGraph &G) {
135
134
return Error::success ();
136
135
}
137
136
138
- // Check that we support the graph's pointer size.
139
- if (G.getPointerSize () != 4 && G.getPointerSize () != 8 )
140
- return make_error<JITLinkError>(
141
- " EHFrameEdgeFixer only supports 32 and 64 bit targets" );
142
-
143
137
LLVM_DEBUG ({
144
138
dbgs () << " EHFrameEdgeFixer: Processing " << EHFrameSectionName << " ...\n " ;
145
139
});
@@ -264,6 +258,7 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
264
258
Error EHFrameEdgeFixer::processCIE (ParseContext &PC, Block &B,
265
259
size_t RecordOffset, size_t RecordLength,
266
260
size_t CIEDeltaFieldOffset) {
261
+ using namespace dwarf ;
267
262
268
263
LLVM_DEBUG (dbgs () << " Record is CIE\n " );
269
264
@@ -334,21 +329,19 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
334
329
uint8_t LSDAPointerEncoding;
335
330
if (auto Err = RecordReader.readInteger (LSDAPointerEncoding))
336
331
return Err;
337
- if (! isSupportedPointerEncoding (LSDAPointerEncoding ))
332
+ if (LSDAPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr ))
338
333
return make_error<JITLinkError>(
339
334
" Unsupported LSDA pointer encoding " +
340
335
formatv (" {0:x2}" , LSDAPointerEncoding) + " in CIE at " +
341
336
formatv (" {0:x16}" , CIESymbol.getAddress ()));
342
- CIEInfo.LSDAPointerEncoding = LSDAPointerEncoding;
343
337
break ;
344
338
}
345
339
case ' P' : {
346
340
uint8_t PersonalityPointerEncoding = 0 ;
347
341
if (auto Err = RecordReader.readInteger (PersonalityPointerEncoding))
348
342
return Err;
349
343
if (PersonalityPointerEncoding !=
350
- (dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
351
- dwarf::DW_EH_PE_sdata4))
344
+ (DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4))
352
345
return make_error<JITLinkError>(
353
346
" Unspported personality pointer "
354
347
" encoding " +
@@ -363,12 +356,12 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
363
356
uint8_t FDEPointerEncoding;
364
357
if (auto Err = RecordReader.readInteger (FDEPointerEncoding))
365
358
return Err;
366
- if (! isSupportedPointerEncoding (FDEPointerEncoding ))
359
+ if (FDEPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr ))
367
360
return make_error<JITLinkError>(
368
- " Unsupported FDE pointer encoding " +
361
+ " Unsupported FDE address pointer "
362
+ " encoding " +
369
363
formatv (" {0:x2}" , FDEPointerEncoding) + " in CIE at " +
370
364
formatv (" {0:x16}" , CIESymbol.getAddress ()));
371
- CIEInfo.FDEPointerEncoding = FDEPointerEncoding;
372
365
break ;
373
366
}
374
367
default :
@@ -452,13 +445,11 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
452
445
JITTargetAddress PCBeginFieldOffset = RecordReader.getOffset ();
453
446
auto PCEdgeItr = BlockEdges.find (RecordOffset + PCBeginFieldOffset);
454
447
if (PCEdgeItr == BlockEdges.end ()) {
455
- auto PCBeginPtrInfo =
456
- readEncodedPointer (CIEInfo->FDEPointerEncoding ,
457
- RecordAddress + PCBeginFieldOffset, RecordReader);
458
- if (!PCBeginPtrInfo)
459
- return PCBeginPtrInfo.takeError ();
460
- JITTargetAddress PCBegin = PCBeginPtrInfo->first ;
461
- Edge::Kind PCBeginEdgeKind = PCBeginPtrInfo->second ;
448
+ auto PCBeginDelta = readAbsolutePointer (PC.G , RecordReader);
449
+ if (!PCBeginDelta)
450
+ return PCBeginDelta.takeError ();
451
+ JITTargetAddress PCBegin =
452
+ RecordAddress + PCBeginFieldOffset + *PCBeginDelta;
462
453
LLVM_DEBUG ({
463
454
dbgs () << " Adding edge at "
464
455
<< formatv (" {0:x16}" , RecordAddress + PCBeginFieldOffset)
@@ -467,8 +458,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
467
458
auto PCBeginSym = getOrCreateSymbol (PC, PCBegin);
468
459
if (!PCBeginSym)
469
460
return PCBeginSym.takeError ();
470
- B.addEdge (PCBeginEdgeKind, RecordOffset + PCBeginFieldOffset, *PCBeginSym,
471
- 0 );
461
+ B.addEdge (Delta64, RecordOffset + PCBeginFieldOffset, *PCBeginSym, 0 );
472
462
PCBeginBlock = &PCBeginSym->getBlock ();
473
463
} else {
474
464
auto &EI = PCEdgeItr->second ;
@@ -489,42 +479,38 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
489
479
" points at external block" );
490
480
}
491
481
PCBeginBlock = &EI.Target ->getBlock ();
492
- if (auto Err = RecordReader.skip (
493
- getPointerEncodingDataSize (CIEInfo->FDEPointerEncoding )))
482
+ if (auto Err = RecordReader.skip (PC.G .getPointerSize ()))
494
483
return Err;
495
484
}
496
485
497
486
// Add a keep-alive edge from the FDE target to the FDE to ensure that the
498
487
// FDE is kept alive if its target is.
499
488
assert (PCBeginBlock && " PC-begin block not recorded" );
500
- LLVM_DEBUG ({
501
- dbgs () << " Adding keep-alive edge from target at "
502
- << formatv (" {0:x16}" , PCBeginBlock->getAddress ()) << " to FDE at "
503
- << formatv (" {0:x16}" , RecordAddress) << " \n " ;
504
- });
505
489
PCBeginBlock->addEdge (Edge::KeepAlive, 0 , FDESymbol, 0 );
506
490
}
507
491
508
492
// Skip over the PC range size field.
509
- if (auto Err = RecordReader.skip (
510
- getPointerEncodingDataSize (CIEInfo->FDEPointerEncoding )))
493
+ if (auto Err = RecordReader.skip (PC.G .getPointerSize ()))
511
494
return Err;
512
495
513
496
if (CIEInfo->FDEsHaveLSDAField ) {
514
497
uint64_t AugmentationDataSize;
515
498
if (auto Err = RecordReader.readULEB128 (AugmentationDataSize))
516
499
return Err;
500
+ if (AugmentationDataSize != PC.G .getPointerSize ())
501
+ return make_error<JITLinkError>(
502
+ " Unexpected FDE augmentation data size (expected " +
503
+ Twine (PC.G .getPointerSize ()) + " , got " +
504
+ Twine (AugmentationDataSize) + " ) for FDE at " +
505
+ formatv (" {0:x16}" , RecordAddress));
517
506
518
507
JITTargetAddress LSDAFieldOffset = RecordReader.getOffset ();
519
508
auto LSDAEdgeItr = BlockEdges.find (RecordOffset + LSDAFieldOffset);
520
509
if (LSDAEdgeItr == BlockEdges.end ()) {
521
- auto LSDAPointerInfo =
522
- readEncodedPointer (CIEInfo->LSDAPointerEncoding ,
523
- RecordAddress + LSDAFieldOffset, RecordReader);
524
- if (!LSDAPointerInfo)
525
- return LSDAPointerInfo.takeError ();
526
- JITTargetAddress LSDA = LSDAPointerInfo->first ;
527
- Edge::Kind LSDAEdgeKind = LSDAPointerInfo->second ;
510
+ auto LSDADelta = readAbsolutePointer (PC.G , RecordReader);
511
+ if (!LSDADelta)
512
+ return LSDADelta.takeError ();
513
+ JITTargetAddress LSDA = RecordAddress + LSDAFieldOffset + *LSDADelta;
528
514
auto LSDASym = getOrCreateSymbol (PC, LSDA);
529
515
if (!LSDASym)
530
516
return LSDASym.takeError ();
@@ -533,7 +519,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
533
519
<< formatv (" {0:x16}" , RecordAddress + LSDAFieldOffset)
534
520
<< " to LSDA at " << formatv (" {0:x16}" , LSDA) << " \n " ;
535
521
});
536
- B.addEdge (LSDAEdgeKind , RecordOffset + LSDAFieldOffset, *LSDASym, 0 );
522
+ B.addEdge (Delta64 , RecordOffset + LSDAFieldOffset, *LSDASym, 0 );
537
523
} else {
538
524
LLVM_DEBUG ({
539
525
auto &EI = LSDAEdgeItr->second ;
@@ -544,7 +530,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
544
530
dbgs () << " + " << formatv (" {0:x16}" , EI.Addend );
545
531
dbgs () << " \n " ;
546
532
});
547
- if (auto Err = RecordReader.skip (AugmentationDataSize ))
533
+ if (auto Err = RecordReader.skip (PC. G . getPointerSize () ))
548
534
return Err;
549
535
}
550
536
} else {
@@ -595,110 +581,23 @@ EHFrameEdgeFixer::parseAugmentationString(BinaryStreamReader &RecordReader) {
595
581
return std::move (AugInfo);
596
582
}
597
583
598
- bool EHFrameEdgeFixer::isSupportedPointerEncoding (uint8_t PointerEncoding) {
599
- using namespace dwarf ;
600
-
601
- // We only support PC-rel for now.
602
- if ((PointerEncoding & 0x70 ) != DW_EH_PE_pcrel)
603
- return false ;
604
-
605
- // readEncodedPointer does not handle indirect.
606
- if (PointerEncoding & DW_EH_PE_indirect)
607
- return false ;
608
-
609
- // Supported datatypes.
610
- switch (PointerEncoding & 0xf ) {
611
- case DW_EH_PE_absptr:
612
- case DW_EH_PE_udata4:
613
- case DW_EH_PE_udata8:
614
- case DW_EH_PE_sdata4:
615
- case DW_EH_PE_sdata8:
616
- return true ;
617
- }
618
-
619
- return false ;
620
- }
621
-
622
- unsigned EHFrameEdgeFixer::getPointerEncodingDataSize (uint8_t PointerEncoding) {
623
- using namespace dwarf ;
624
-
625
- assert (isSupportedPointerEncoding (PointerEncoding) &&
626
- " Unsupported pointer encoding" );
627
- switch (PointerEncoding & 0xf ) {
628
- case DW_EH_PE_absptr:
629
- return PointerSize;
630
- case DW_EH_PE_udata4:
631
- case DW_EH_PE_sdata4:
632
- return 4 ;
633
- case DW_EH_PE_udata8:
634
- case DW_EH_PE_sdata8:
635
- return 8 ;
636
- default :
637
- llvm_unreachable (" Unsupported encoding" );
638
- }
639
- }
640
-
641
- Expected<std::pair<JITTargetAddress, Edge::Kind>>
642
- EHFrameEdgeFixer::readEncodedPointer (uint8_t PointerEncoding,
643
- JITTargetAddress PointerFieldAddress,
644
- BinaryStreamReader &RecordReader) {
584
+ Expected<JITTargetAddress>
585
+ EHFrameEdgeFixer::readAbsolutePointer (LinkGraph &G,
586
+ BinaryStreamReader &RecordReader) {
645
587
static_assert (sizeof (JITTargetAddress) == sizeof (uint64_t ),
646
588
" Result must be able to hold a uint64_t" );
647
- assert (isSupportedPointerEncoding (PointerEncoding) &&
648
- " Unsupported pointer encoding" );
649
-
650
- using namespace dwarf ;
651
-
652
- // Isolate data type, remap absptr to udata4 or udata8. This relies on us
653
- // having verified that the graph uses 32-bit or 64-bit pointers only at the
654
- // start of this pass.
655
- uint8_t EffectiveType = PointerEncoding & 0xf ;
656
- if (EffectiveType == DW_EH_PE_absptr)
657
- EffectiveType = (PointerSize == 8 ) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;
658
-
659
589
JITTargetAddress Addr;
660
- Edge::Kind PointerEdgeKind;
661
- switch (EffectiveType) {
662
- case DW_EH_PE_udata4: {
663
- uint32_t Val;
664
- if (auto Err = RecordReader.readInteger (Val))
590
+ if (G.getPointerSize () == 8 ) {
591
+ if (auto Err = RecordReader.readInteger (Addr))
665
592
return std::move (Err);
666
- Addr = PointerFieldAddress + Val;
667
- PointerEdgeKind = Delta32;
668
- break ;
669
- }
670
- case DW_EH_PE_udata8: {
671
- uint64_t Val;
672
- if (auto Err = RecordReader.readInteger (Val))
593
+ } else if (G.getPointerSize () == 4 ) {
594
+ uint32_t Addr32;
595
+ if (auto Err = RecordReader.readInteger (Addr32))
673
596
return std::move (Err);
674
- Addr = PointerFieldAddress + Val;
675
- PointerEdgeKind = Delta64;
676
- break ;
677
- }
678
- case DW_EH_PE_sdata4: {
679
- int32_t Val;
680
- if (auto Err = RecordReader.readInteger (Val))
681
- return std::move (Err);
682
- Addr = PointerFieldAddress + Val;
683
- PointerEdgeKind = Delta32;
684
- break ;
685
- }
686
- case DW_EH_PE_sdata8: {
687
- int64_t Val;
688
- if (auto Err = RecordReader.readInteger (Val))
689
- return std::move (Err);
690
- Addr = PointerFieldAddress + Val;
691
- PointerEdgeKind = Delta64;
692
- break ;
693
- }
694
- }
695
-
696
- if (PointerEdgeKind == Edge::Invalid)
697
- return make_error<JITLinkError>(
698
- " Unspported edge kind for encoded pointer at " +
699
- formatv (" {0:x}" , PointerFieldAddress));
700
-
701
- return std::make_pair (Addr, Delta64);
597
+ Addr = Addr32;
598
+ } else
599
+ llvm_unreachable (" Pointer size is not 32-bit or 64-bit" );
600
+ return Addr;
702
601
}
703
602
704
603
Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol (ParseContext &PC,
0 commit comments