@@ -58,10 +58,10 @@ unsigned EHStreamer::sharedTypeIDs(const LandingPadInfo *L,
58
58
59
59
// / Compute the actions table and gather the first action index for each landing
60
60
// / pad site.
61
- unsigned EHStreamer::
62
- computeActionsTable ( const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
63
- SmallVectorImpl<ActionEntry> &Actions,
64
- SmallVectorImpl<unsigned > &FirstActions) {
61
+ void EHStreamer::computeActionsTable (
62
+ const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
63
+ SmallVectorImpl<ActionEntry> &Actions,
64
+ SmallVectorImpl<unsigned > &FirstActions) {
65
65
// The action table follows the call-site table in the LSDA. The individual
66
66
// records are of two types:
67
67
//
@@ -161,8 +161,6 @@ computeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
161
161
162
162
PrevLPI = LPI;
163
163
}
164
-
165
- return SizeActions;
166
164
}
167
165
168
166
// / Return `true' if this is a call to a function marked `nounwind'. Return
@@ -369,47 +367,23 @@ void EHStreamer::emitExceptionTable() {
369
367
// landing pad site.
370
368
SmallVector<ActionEntry, 32 > Actions;
371
369
SmallVector<unsigned , 64 > FirstActions;
372
- unsigned SizeActions =
373
- computeActionsTable (LandingPads, Actions, FirstActions);
370
+ computeActionsTable (LandingPads, Actions, FirstActions);
374
371
375
372
// Compute the call-site table.
376
373
SmallVector<CallSiteEntry, 64 > CallSites;
377
374
computeCallSiteTable (CallSites, LandingPads, FirstActions);
378
375
379
- // Final tallies.
380
-
381
- // Call sites.
382
376
bool IsSJLJ = Asm->MAI ->getExceptionHandlingType () == ExceptionHandling::SjLj;
383
377
bool HaveTTData = IsSJLJ ? (!TypeInfos.empty () || !FilterIds.empty ()) : true ;
384
378
385
- unsigned CallSiteTableLength;
386
- if (IsSJLJ)
387
- CallSiteTableLength = 0 ;
388
- else {
389
- unsigned SiteStartSize = 4 ; // dwarf::DW_EH_PE_udata4
390
- unsigned SiteLengthSize = 4 ; // dwarf::DW_EH_PE_udata4
391
- unsigned LandingPadSize = 4 ; // dwarf::DW_EH_PE_udata4
392
- CallSiteTableLength =
393
- CallSites.size () * (SiteStartSize + SiteLengthSize + LandingPadSize);
394
- }
395
-
396
- for (unsigned i = 0 , e = CallSites.size (); i < e; ++i) {
397
- CallSiteTableLength += getULEB128Size (CallSites[i].Action );
398
- if (IsSJLJ)
399
- CallSiteTableLength += getULEB128Size (i);
400
- }
401
-
402
379
// Type infos.
403
380
MCSection *LSDASection = Asm->getObjFileLowering ().getLSDASection ();
404
381
unsigned TTypeEncoding;
405
- unsigned TypeFormatSize;
406
382
407
383
if (!HaveTTData) {
408
384
// For SjLj exceptions, if there is no TypeInfo, then we just explicitly say
409
385
// that we're omitting that bit.
410
386
TTypeEncoding = dwarf::DW_EH_PE_omit;
411
- // dwarf::DW_EH_PE_absptr
412
- TypeFormatSize = Asm->getDataLayout ().getPointerSize ();
413
387
} else {
414
388
// Okay, we have actual filters or typeinfos to emit. As such, we need to
415
389
// pick a type encoding for them. We're about to emit a list of pointers to
@@ -439,7 +413,6 @@ void EHStreamer::emitExceptionTable() {
439
413
// in target-independent code.
440
414
//
441
415
TTypeEncoding = Asm->getObjFileLowering ().getTTypeEncoding ();
442
- TypeFormatSize = Asm->GetSizeOfEncodedValue (TTypeEncoding);
443
416
}
444
417
445
418
// Begin the exception table.
@@ -460,64 +433,35 @@ void EHStreamer::emitExceptionTable() {
460
433
Asm->EmitEncodingByte (dwarf::DW_EH_PE_omit, " @LPStart" );
461
434
Asm->EmitEncodingByte (TTypeEncoding, " @TType" );
462
435
463
- // The type infos need to be aligned. GCC does this by inserting padding just
464
- // before the type infos. However, this changes the size of the exception
465
- // table, so you need to take this into account when you output the exception
466
- // table size. However, the size is output using a variable length encoding.
467
- // So by increasing the size by inserting padding, you may increase the number
468
- // of bytes used for writing the size. If it increases, say by one byte, then
469
- // you now need to output one less byte of padding to get the type infos
470
- // aligned. However this decreases the size of the exception table. This
471
- // changes the value you have to output for the exception table size. Due to
472
- // the variable length encoding, the number of bytes used for writing the
473
- // length may decrease. If so, you then have to increase the amount of
474
- // padding. And so on. If you look carefully at the GCC code you will see that
475
- // it indeed does this in a loop, going on and on until the values stabilize.
476
- // We chose another solution: don't output padding inside the table like GCC
477
- // does, instead output it before the table.
478
- unsigned SizeTypes = TypeInfos.size () * TypeFormatSize;
479
- unsigned CallSiteTableLengthSize = getULEB128Size (CallSiteTableLength);
480
- unsigned TTypeBaseOffset =
481
- sizeof (int8_t ) + // Call site format
482
- CallSiteTableLengthSize + // Call site table length size
483
- CallSiteTableLength + // Call site table length
484
- SizeActions + // Actions size
485
- SizeTypes;
486
- unsigned TTypeBaseOffsetSize = getULEB128Size (TTypeBaseOffset);
487
- unsigned TotalSize =
488
- sizeof (int8_t ) + // LPStart format
489
- sizeof (int8_t ) + // TType format
490
- (HaveTTData ? TTypeBaseOffsetSize : 0 ) + // TType base offset size
491
- TTypeBaseOffset; // TType base offset
492
- unsigned PadBytes = (4 - TotalSize) & 3 ;
493
-
436
+ MCSymbol *TTBaseLabel = nullptr ;
494
437
if (HaveTTData) {
495
- // Account for any extra padding that will be added to the call site table
496
- // length.
497
- Asm->EmitPaddedULEB128 (TTypeBaseOffset, TTypeBaseOffsetSize + PadBytes,
498
- " @TType base offset" );
499
- PadBytes = 0 ;
438
+ // N.B.: There is a dependency loop between the size of the TTBase uleb128
439
+ // here and the amount of padding before the aligned type table. The
440
+ // assembler must sometimes pad this uleb128 or insert extra padding before
441
+ // the type table. See PR35809 or GNU as bug 4029.
442
+ MCSymbol *TTBaseRefLabel = Asm->createTempSymbol (" ttbaseref" );
443
+ TTBaseLabel = Asm->createTempSymbol (" ttbase" );
444
+ Asm->EmitLabelDifferenceAsULEB128 (TTBaseLabel, TTBaseRefLabel);
445
+ Asm->OutStreamer ->EmitLabel (TTBaseRefLabel);
500
446
}
501
447
502
448
bool VerboseAsm = Asm->OutStreamer ->isVerboseAsm ();
503
449
450
+ // Emit the landing pad call site table.
451
+ MCSymbol *CstBeginLabel = Asm->createTempSymbol (" cst_begin" );
452
+ MCSymbol *CstEndLabel = Asm->createTempSymbol (" cst_end" );
453
+ Asm->EmitEncodingByte (dwarf::DW_EH_PE_udata4, " Call site" );
454
+ Asm->EmitLabelDifferenceAsULEB128 (CstEndLabel, CstBeginLabel);
455
+ Asm->OutStreamer ->EmitLabel (CstBeginLabel);
456
+
504
457
// SjLj Exception handling
505
458
if (IsSJLJ) {
506
- Asm->EmitEncodingByte (dwarf::DW_EH_PE_udata4, " Call site" );
507
-
508
- // Add extra padding if it wasn't added to the TType base offset.
509
- Asm->EmitPaddedULEB128 (CallSiteTableLength,
510
- CallSiteTableLengthSize + PadBytes,
511
- " Call site table length" );
512
-
513
- // Emit the landing pad site information.
514
459
unsigned idx = 0 ;
515
460
for (SmallVectorImpl<CallSiteEntry>::const_iterator
516
461
I = CallSites.begin (), E = CallSites.end (); I != E; ++I, ++idx) {
517
462
const CallSiteEntry &S = *I;
518
463
519
- // Offset of the landing pad, counted in 16-byte bundles relative to the
520
- // @LPStart address.
464
+ // Index of the call site entry.
521
465
if (VerboseAsm) {
522
466
Asm->OutStreamer ->AddComment (" >> Call Site " + Twine (idx) + " <<" );
523
467
Asm->OutStreamer ->AddComment (" On exception at call site " +Twine (idx));
@@ -557,14 +501,6 @@ void EHStreamer::emitExceptionTable() {
557
501
// A missing entry in the call-site table indicates that a call is not
558
502
// supposed to throw.
559
503
560
- // Emit the landing pad call site table.
561
- Asm->EmitEncodingByte (dwarf::DW_EH_PE_udata4, " Call site" );
562
-
563
- // Add extra padding if it wasn't added to the TType base offset.
564
- Asm->EmitPaddedULEB128 (CallSiteTableLength,
565
- CallSiteTableLengthSize + PadBytes,
566
- " Call site table length" );
567
-
568
504
unsigned Entry = 0 ;
569
505
for (SmallVectorImpl<CallSiteEntry>::const_iterator
570
506
I = CallSites.begin (), E = CallSites.end (); I != E; ++I) {
@@ -579,9 +515,7 @@ void EHStreamer::emitExceptionTable() {
579
515
if (!EndLabel)
580
516
EndLabel = Asm->getFunctionEnd ();
581
517
582
- // Offset of the call site relative to the previous call site, counted in
583
- // number of 16-byte bundles. The first call site is counted relative to
584
- // the start of the procedure fragment.
518
+ // Offset of the call site relative to the start of the procedure.
585
519
if (VerboseAsm)
586
520
Asm->OutStreamer ->AddComment (" >> Call Site " + Twine (++Entry) + " <<" );
587
521
Asm->EmitLabelDifference (BeginLabel, EHFuncBeginSym, 4 );
@@ -591,8 +525,7 @@ void EHStreamer::emitExceptionTable() {
591
525
EndLabel->getName ());
592
526
Asm->EmitLabelDifference (EndLabel, BeginLabel, 4 );
593
527
594
- // Offset of the landing pad, counted in 16-byte bundles relative to the
595
- // @LPStart address.
528
+ // Offset of the landing pad relative to the start of the procedure.
596
529
if (!S.LPad ) {
597
530
if (VerboseAsm)
598
531
Asm->OutStreamer ->AddComment (" has no landing pad" );
@@ -617,6 +550,7 @@ void EHStreamer::emitExceptionTable() {
617
550
Asm->EmitULEB128 (S.Action );
618
551
}
619
552
}
553
+ Asm->OutStreamer ->EmitLabel (CstEndLabel);
620
554
621
555
// Emit the Action Table.
622
556
int Entry = 0 ;
@@ -660,12 +594,15 @@ void EHStreamer::emitExceptionTable() {
660
594
Asm->EmitSLEB128 (Action.NextAction );
661
595
}
662
596
663
- emitTypeInfos (TTypeEncoding);
597
+ if (HaveTTData) {
598
+ Asm->EmitAlignment (2 );
599
+ emitTypeInfos (TTypeEncoding, TTBaseLabel);
600
+ }
664
601
665
602
Asm->EmitAlignment (2 );
666
603
}
667
604
668
- void EHStreamer::emitTypeInfos (unsigned TTypeEncoding) {
605
+ void EHStreamer::emitTypeInfos (unsigned TTypeEncoding, MCSymbol *TTBaseLabel ) {
669
606
const MachineFunction *MF = Asm->MF ;
670
607
const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos ();
671
608
const std::vector<unsigned > &FilterIds = MF->getFilterIds ();
@@ -687,6 +624,8 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) {
687
624
Asm->EmitTTypeReference (GV, TTypeEncoding);
688
625
}
689
626
627
+ Asm->OutStreamer ->EmitLabel (TTBaseLabel);
628
+
690
629
// Emit the Exception Specifications.
691
630
if (VerboseAsm && !FilterIds.empty ()) {
692
631
Asm->OutStreamer ->AddComment (" >> Filter TypeInfos <<" );
0 commit comments