19
19
#include " llvm/MC/MCObjectFileInfo.h"
20
20
#include " llvm/MC/MCObjectStreamer.h"
21
21
#include " llvm/MC/MCRegisterInfo.h"
22
+ #include " llvm/MC/MCSection.h"
22
23
#include " llvm/MC/MCSymbol.h"
23
24
#include " llvm/Support/Debug.h"
24
25
#include " llvm/Support/ErrorHandling.h"
@@ -518,8 +519,12 @@ static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
518
519
MCOS->EmitULEB128IntValue (dwarf::DW_TAG_compile_unit);
519
520
MCOS->EmitIntValue (dwarf::DW_CHILDREN_yes, 1 );
520
521
EmitAbbrev (MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
521
- EmitAbbrev (MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
522
- EmitAbbrev (MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
522
+ if (MCOS->getContext ().getGenDwarfSectionSyms ().size () > 1 ) {
523
+ EmitAbbrev (MCOS, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4);
524
+ } else {
525
+ EmitAbbrev (MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
526
+ EmitAbbrev (MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
527
+ }
523
528
EmitAbbrev (MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
524
529
if (!context.getCompilationDir ().empty ())
525
530
EmitAbbrev (MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
@@ -552,20 +557,14 @@ static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
552
557
}
553
558
554
559
// When generating dwarf for assembly source files this emits the data for
555
- // .debug_aranges section. Which contains a header and a table of pairs of
556
- // PointerSize'ed values for the address and size of section(s) with line table
557
- // entries (just the default .text in our case) and a terminating pair of zeros .
560
+ // .debug_aranges section. This section contains a header and a table of pairs
561
+ // of PointerSize'ed values for the address and size of section(s) with line
562
+ // table entries .
558
563
static void EmitGenDwarfAranges (MCStreamer *MCOS,
559
564
const MCSymbol *InfoSectionSymbol) {
560
565
MCContext &context = MCOS->getContext ();
561
566
562
- // Create a symbol at the end of the section that we are creating the dwarf
563
- // debugging info to use later in here as part of the expression to calculate
564
- // the size of the section for the table.
565
- MCOS->SwitchSection (context.getGenDwarfSection ());
566
- MCSymbol *SectionEndSym = context.CreateTempSymbol ();
567
- MCOS->EmitLabel (SectionEndSym);
568
- context.setGenDwarfSectionEndSym (SectionEndSym);
567
+ auto &Sections = context.getGenDwarfSectionSyms ();
569
568
570
569
MCOS->SwitchSection (context.getObjectFileInfo ()->getDwarfARangesSection ());
571
570
@@ -583,8 +582,8 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
583
582
Length += Pad;
584
583
585
584
// Add the size of the pair of PointerSize'ed values for the address and size
586
- // of the one default .text section we have in the table.
587
- Length += 2 * AddrSize;
585
+ // of each section we have in the table.
586
+ Length += 2 * AddrSize * Sections. size () ;
588
587
// And the pair of terminating zeros.
589
588
Length += 2 * AddrSize;
590
589
@@ -608,14 +607,21 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
608
607
for (int i = 0 ; i < Pad; i++)
609
608
MCOS->EmitIntValue (0 , 1 );
610
609
611
- // Now emit the table of pairs of PointerSize'ed values for the section(s)
612
- // address and size, in our case just the one default .text section.
613
- const MCExpr *Addr = MCSymbolRefExpr::Create (
614
- context.getGenDwarfSectionStartSym (), MCSymbolRefExpr::VK_None, context);
615
- const MCExpr *Size = MakeStartMinusEndExpr (*MCOS,
616
- *context.getGenDwarfSectionStartSym (), *SectionEndSym, 0 );
617
- MCOS->EmitValue (Addr, AddrSize);
618
- MCOS->EmitAbsValue (Size, AddrSize);
610
+ // Now emit the table of pairs of PointerSize'ed values for the section
611
+ // addresses and sizes.
612
+ for (const auto &sec : Sections) {
613
+ MCSymbol* StartSymbol = sec.second .first ;
614
+ MCSymbol* EndSymbol = sec.second .second ;
615
+ assert (StartSymbol && " StartSymbol must not be NULL" );
616
+ assert (EndSymbol && " EndSymbol must not be NULL" );
617
+
618
+ const MCExpr *Addr = MCSymbolRefExpr::Create (
619
+ StartSymbol, MCSymbolRefExpr::VK_None, context);
620
+ const MCExpr *Size = MakeStartMinusEndExpr (*MCOS,
621
+ *StartSymbol, *EndSymbol, 0 );
622
+ MCOS->EmitValue (Addr, AddrSize);
623
+ MCOS->EmitAbsValue (Size, AddrSize);
624
+ }
619
625
620
626
// And finally the pair of terminating zeros.
621
627
MCOS->EmitIntValue (0 , AddrSize);
@@ -627,7 +633,8 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
627
633
// DIE and a list of label DIEs.
628
634
static void EmitGenDwarfInfo (MCStreamer *MCOS,
629
635
const MCSymbol *AbbrevSectionSymbol,
630
- const MCSymbol *LineSectionSymbol) {
636
+ const MCSymbol *LineSectionSymbol,
637
+ const MCSymbol *RangesSectionSymbol) {
631
638
MCContext &context = MCOS->getContext ();
632
639
633
640
MCOS->SwitchSection (context.getObjectFileInfo ()->getDwarfInfoSection ());
@@ -674,15 +681,37 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
674
681
MCOS->EmitIntValue (0 , 4 );
675
682
}
676
683
677
- // AT_low_pc, the first address of the default .text section.
678
- const MCExpr *Start = MCSymbolRefExpr::Create (
679
- context.getGenDwarfSectionStartSym (), MCSymbolRefExpr::VK_None, context);
680
- MCOS->EmitValue (Start, AddrSize);
684
+ if (RangesSectionSymbol) {
685
+ // There are multiple sections containing code, so we must use the
686
+ // .debug_ranges sections.
681
687
682
- // AT_high_pc, the last address of the default .text section.
683
- const MCExpr *End = MCSymbolRefExpr::Create (
684
- context.getGenDwarfSectionEndSym (), MCSymbolRefExpr::VK_None, context);
685
- MCOS->EmitValue (End, AddrSize);
688
+ // AT_ranges, the 4 byte offset from the start of the .debug_ranges section
689
+ // to the address range list for this compilation unit.
690
+ MCOS->EmitSymbolValue (RangesSectionSymbol, 4 );
691
+ } else {
692
+ // If we only have one non-empty code section, we can use the simpler
693
+ // AT_low_pc and AT_high_pc attributes.
694
+
695
+ // Find the first (and only) non-empty text section
696
+ auto &Sections = context.getGenDwarfSectionSyms ();
697
+ const auto TextSection = Sections.begin ();
698
+ assert (TextSection != Sections.end () && " No text section found" );
699
+
700
+ MCSymbol* StartSymbol = TextSection->second .first ;
701
+ MCSymbol* EndSymbol = TextSection->second .second ;
702
+ assert (StartSymbol && " StartSymbol must not be NULL" );
703
+ assert (EndSymbol && " EndSymbol must not be NULL" );
704
+
705
+ // AT_low_pc, the first address of the default .text section.
706
+ const MCExpr *Start = MCSymbolRefExpr::Create (
707
+ StartSymbol, MCSymbolRefExpr::VK_None, context);
708
+ MCOS->EmitValue (Start, AddrSize);
709
+
710
+ // AT_high_pc, the last address of the default .text section.
711
+ const MCExpr *End = MCSymbolRefExpr::Create (
712
+ EndSymbol, MCSymbolRefExpr::VK_None, context);
713
+ MCOS->EmitValue (End, AddrSize);
714
+ }
686
715
687
716
// AT_name, the name of the source file. Reconstruct from the first directory
688
717
// and file table entries.
@@ -766,13 +795,51 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
766
795
MCOS->EmitLabel (InfoEnd);
767
796
}
768
797
798
+ // When generating dwarf for assembly source files this emits the data for
799
+ // .debug_ranges section. We only emit one range list, which spans all of the
800
+ // executable sections of this file.
801
+ static void EmitGenDwarfRanges (MCStreamer *MCOS) {
802
+ MCContext &context = MCOS->getContext ();
803
+ auto &Sections = context.getGenDwarfSectionSyms ();
804
+
805
+ const MCAsmInfo *AsmInfo = context.getAsmInfo ();
806
+ int AddrSize = AsmInfo->getPointerSize ();
807
+
808
+ MCOS->SwitchSection (context.getObjectFileInfo ()->getDwarfRangesSection ());
809
+
810
+ for (const auto sec : Sections) {
811
+
812
+ MCSymbol* StartSymbol = sec.second .first ;
813
+ MCSymbol* EndSymbol = sec.second .second ;
814
+ assert (StartSymbol && " StartSymbol must not be NULL" );
815
+ assert (EndSymbol && " EndSymbol must not be NULL" );
816
+
817
+ // Emit a base address selection entry for the start of this section
818
+ const MCExpr *SectionStartAddr = MCSymbolRefExpr::Create (
819
+ StartSymbol, MCSymbolRefExpr::VK_None, context);
820
+ MCOS->EmitFill (AddrSize, 0xFF );
821
+ MCOS->EmitValue (SectionStartAddr, AddrSize);
822
+
823
+ // Emit a range list entry spanning this section
824
+ const MCExpr *SectionSize = MakeStartMinusEndExpr (*MCOS,
825
+ *StartSymbol, *EndSymbol, 0 );
826
+ MCOS->EmitIntValue (0 , AddrSize);
827
+ MCOS->EmitAbsValue (SectionSize, AddrSize);
828
+ }
829
+
830
+ // Emit end of list entry
831
+ MCOS->EmitIntValue (0 , AddrSize);
832
+ MCOS->EmitIntValue (0 , AddrSize);
833
+ }
834
+
769
835
//
770
836
// When generating dwarf for assembly source files this emits the Dwarf
771
837
// sections.
772
838
//
773
839
void MCGenDwarfInfo::Emit (MCStreamer *MCOS) {
774
- // Create the dwarf sections in this order (.debug_line already created).
775
840
MCContext &context = MCOS->getContext ();
841
+
842
+ // Create the dwarf sections in this order (.debug_line already created).
776
843
const MCAsmInfo *AsmInfo = context.getAsmInfo ();
777
844
bool CreateDwarfSectionSymbols =
778
845
AsmInfo->doesDwarfUseRelocationsAcrossSections ();
@@ -781,6 +848,22 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
781
848
LineSectionSymbol = MCOS->getDwarfLineTableSymbol (0 );
782
849
MCSymbol *AbbrevSectionSymbol = nullptr ;
783
850
MCSymbol *InfoSectionSymbol = nullptr ;
851
+ MCSymbol *RangesSectionSymbol = NULL ;
852
+
853
+ // Create end symbols for each section, and remove empty sections
854
+ MCOS->getContext ().finalizeDwarfSections (*MCOS);
855
+
856
+ // If there are no sections to generate debug info for, we don't need
857
+ // to do anything
858
+ if (MCOS->getContext ().getGenDwarfSectionSyms ().empty ())
859
+ return ;
860
+
861
+ // We only need to use the .debug_ranges section if we have multiple
862
+ // code sections.
863
+ const bool UseRangesSection =
864
+ MCOS->getContext ().getGenDwarfSectionSyms ().size () > 1 ;
865
+ CreateDwarfSectionSymbols |= UseRangesSection;
866
+
784
867
MCOS->SwitchSection (context.getObjectFileInfo ()->getDwarfInfoSection ());
785
868
if (CreateDwarfSectionSymbols) {
786
869
InfoSectionSymbol = context.CreateTempSymbol ();
@@ -791,20 +874,30 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
791
874
AbbrevSectionSymbol = context.CreateTempSymbol ();
792
875
MCOS->EmitLabel (AbbrevSectionSymbol);
793
876
}
794
- MCOS->SwitchSection (context.getObjectFileInfo ()->getDwarfARangesSection ());
877
+ if (UseRangesSection) {
878
+ MCOS->SwitchSection (context.getObjectFileInfo ()->getDwarfRangesSection ());
879
+ if (CreateDwarfSectionSymbols) {
880
+ RangesSectionSymbol = context.CreateTempSymbol ();
881
+ MCOS->EmitLabel (RangesSectionSymbol);
882
+ }
883
+ }
795
884
796
- // If there are no line table entries then do not emit any section contents.
797
- if (!context. hasMCLineSections ())
798
- return ;
885
+ assert ((RangesSectionSymbol != NULL ) || !UseRangesSection);
886
+
887
+ MCOS-> SwitchSection (context. getObjectFileInfo ()-> getDwarfARangesSection ()) ;
799
888
800
889
// Output the data for .debug_aranges section.
801
890
EmitGenDwarfAranges (MCOS, InfoSectionSymbol);
802
891
892
+ if (UseRangesSection)
893
+ EmitGenDwarfRanges (MCOS);
894
+
803
895
// Output the data for .debug_abbrev section.
804
896
EmitGenDwarfAbbrev (MCOS);
805
897
806
898
// Output the data for .debug_info section.
807
- EmitGenDwarfInfo (MCOS, AbbrevSectionSymbol, LineSectionSymbol);
899
+ EmitGenDwarfInfo (MCOS, AbbrevSectionSymbol, LineSectionSymbol,
900
+ RangesSectionSymbol);
808
901
}
809
902
810
903
//
@@ -815,12 +908,13 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
815
908
//
816
909
void MCGenDwarfLabelEntry::Make (MCSymbol *Symbol, MCStreamer *MCOS,
817
910
SourceMgr &SrcMgr, SMLoc &Loc) {
818
- // We won't create dwarf labels for temporary symbols or symbols not in
819
- // the default text.
911
+ // We won't create dwarf labels for temporary symbols.
820
912
if (Symbol->isTemporary ())
821
913
return ;
822
914
MCContext &context = MCOS->getContext ();
823
- if (context.getGenDwarfSection () != MCOS->getCurrentSection ().first )
915
+ // We won't create dwarf labels for symbols in sections that we are not
916
+ // generating debug info for.
917
+ if (!context.getGenDwarfSectionSyms ().count (MCOS->getCurrentSection ().first ))
824
918
return ;
825
919
826
920
// The dwarf label's name does not have the symbol name's leading
0 commit comments