@@ -924,7 +924,7 @@ void DwarfDebug::beginModule() {
924
924
MMI->setDebugInfoAvailability (true );
925
925
926
926
// Prime section data.
927
- SectionMap. insert ( Asm->getObjFileLowering ().getTextSection ()) ;
927
+ SectionMap[ Asm->getObjFileLowering ().getTextSection ()] ;
928
928
}
929
929
930
930
// Attach DW_AT_inline attribute with inlined subprogram DIEs.
@@ -1077,16 +1077,39 @@ void DwarfDebug::finalizeModuleInfo() {
1077
1077
}
1078
1078
1079
1079
void DwarfDebug::endSections () {
1080
- // Standard sections final addresses.
1081
- Asm->OutStreamer .SwitchSection (Asm->getObjFileLowering ().getTextSection ());
1082
- Asm->OutStreamer .EmitLabel (Asm->GetTempSymbol (" text_end" ));
1083
- Asm->OutStreamer .SwitchSection (Asm->getObjFileLowering ().getDataSection ());
1084
- Asm->OutStreamer .EmitLabel (Asm->GetTempSymbol (" data_end" ));
1080
+ // Filter labels by section.
1081
+ for (size_t n = 0 ; n < Labels.size (); n++) {
1082
+ const SymbolCU &SCU = Labels[n];
1083
+ if (SCU.Sym ->isInSection ()) {
1084
+ // Make a note of this symbol and it's section.
1085
+ const MCSection *Section = &SCU.Sym ->getSection ();
1086
+ if (!Section->getKind ().isMetadata ())
1087
+ SectionMap[Section].push_back (SCU);
1088
+ } else {
1089
+ // Some symbols (e.g. common/bss on mach-o) can have no section but still
1090
+ // appear in the output. This sucks as we rely on sections to build
1091
+ // arange spans. We can do it without, but it's icky.
1092
+ SectionMap[NULL ].push_back (SCU);
1093
+ }
1094
+ }
1095
+
1096
+ // Add terminating symbols for each section.
1097
+ for (SectionMapType::iterator it = SectionMap.begin (); it != SectionMap.end ();
1098
+ it++) {
1099
+ const MCSection *Section = it->first ;
1100
+ MCSymbol *Sym = NULL ;
1085
1101
1086
- // End text sections.
1087
- for (unsigned I = 0 , E = SectionMap.size (); I != E; ++I) {
1088
- Asm->OutStreamer .SwitchSection (SectionMap[I]);
1089
- Asm->OutStreamer .EmitLabel (Asm->GetTempSymbol (" section_end" , I+1 ));
1102
+ if (Section) {
1103
+ Sym = Asm->GetTempSymbol (Section->getLabelEndName ());
1104
+ Asm->OutStreamer .SwitchSection (Section);
1105
+ Asm->OutStreamer .EmitLabel (Sym);
1106
+ }
1107
+
1108
+ // Insert a final terminator.
1109
+ SymbolCU Entry;
1110
+ Entry.CU = NULL ;
1111
+ Entry.Sym = Sym;
1112
+ SectionMap[Section].push_back (Entry);
1090
1113
}
1091
1114
}
1092
1115
@@ -2659,11 +2682,172 @@ void DwarfDebug::emitDebugLoc() {
2659
2682
}
2660
2683
}
2661
2684
2662
- // Emit visible names into a debug aranges section.
2685
+ struct SymbolCUSorter {
2686
+ SymbolCUSorter (const MCStreamer &s) : Streamer(s) {}
2687
+ const MCStreamer &Streamer;
2688
+
2689
+ bool operator () (const SymbolCU &A, const SymbolCU &B) {
2690
+ unsigned IA = A.Sym ? Streamer.GetSymbolOrder (A.Sym ) : 0 ;
2691
+ unsigned IB = B.Sym ? Streamer.GetSymbolOrder (B.Sym ) : 0 ;
2692
+
2693
+ // Symbols with no order assigned should be placed at the end.
2694
+ // (e.g. section end labels)
2695
+ if (IA == 0 )
2696
+ IA = (unsigned )(-1 );
2697
+ if (IB == 0 )
2698
+ IB = (unsigned )(-1 );
2699
+ return IA < IB;
2700
+ }
2701
+ };
2702
+
2703
+ static bool SectionSort (const MCSection *A, const MCSection *B) {
2704
+ std::string LA = (A ? A->getLabelBeginName () : " " );
2705
+ std::string LB = (B ? B->getLabelBeginName () : " " );
2706
+ return LA < LB;
2707
+ }
2708
+
2709
+ static bool CUSort (const CompileUnit *A, const CompileUnit *B) {
2710
+ return (A->getUniqueID () < B->getUniqueID ());
2711
+ }
2712
+
2713
+ struct ArangeSpan {
2714
+ const MCSymbol *Start, *End;
2715
+ };
2716
+
2717
+ // Emit a debug aranges section, containing a CU lookup for any
2718
+ // address we can tie back to a CU.
2663
2719
void DwarfDebug::emitDebugARanges () {
2664
2720
// Start the dwarf aranges section.
2665
2721
Asm->OutStreamer
2666
2722
.SwitchSection (Asm->getObjFileLowering ().getDwarfARangesSection ());
2723
+
2724
+ typedef DenseMap<CompileUnit *, std::vector<ArangeSpan> > SpansType;
2725
+
2726
+ SpansType Spans;
2727
+
2728
+ // Build a list of sections used.
2729
+ std::vector<const MCSection *> Sections;
2730
+ for (SectionMapType::iterator it = SectionMap.begin (); it != SectionMap.end ();
2731
+ it++) {
2732
+ const MCSection *Section = it->first ;
2733
+ Sections.push_back (Section);
2734
+ }
2735
+
2736
+ // Sort the sections into order.
2737
+ // This is only done to ensure consistent output order across different runs.
2738
+ std::sort (Sections.begin (), Sections.end (), SectionSort);
2739
+
2740
+ // Build a set of address spans, sorted by CU.
2741
+ for (size_t SecIdx=0 ;SecIdx<Sections.size ();SecIdx++) {
2742
+ const MCSection *Section = Sections[SecIdx];
2743
+ SmallVector<SymbolCU, 8 > &List = SectionMap[Section];
2744
+ if (List.size () < 2 )
2745
+ continue ;
2746
+
2747
+ // Sort the symbols by offset within the section.
2748
+ SymbolCUSorter sorter (Asm->OutStreamer );
2749
+ std::sort (List.begin (), List.end (), sorter);
2750
+
2751
+ // If we have no section (e.g. common), just write out
2752
+ // individual spans for each symbol.
2753
+ if (Section == NULL ) {
2754
+ for (size_t n = 0 ; n < List.size (); n++) {
2755
+ const SymbolCU &Cur = List[n];
2756
+
2757
+ ArangeSpan Span;
2758
+ Span.Start = Cur.Sym ;
2759
+ Span.End = NULL ;
2760
+ if (Cur.CU )
2761
+ Spans[Cur.CU ].push_back (Span);
2762
+ }
2763
+ } else {
2764
+ // Build spans between each label.
2765
+ const MCSymbol *StartSym = List[0 ].Sym ;
2766
+ for (size_t n = 1 ; n < List.size (); n++) {
2767
+ const SymbolCU &Prev = List[n - 1 ];
2768
+ const SymbolCU &Cur = List[n];
2769
+
2770
+ // Try and build the longest span we can within the same CU.
2771
+ if (Cur.CU != Prev.CU ) {
2772
+ ArangeSpan Span;
2773
+ Span.Start = StartSym;
2774
+ Span.End = Cur.Sym ;
2775
+ Spans[Prev.CU ].push_back (Span);
2776
+ StartSym = Cur.Sym ;
2777
+ }
2778
+ }
2779
+ }
2780
+ }
2781
+
2782
+ const MCSection *ISec = Asm->getObjFileLowering ().getDwarfInfoSection ();
2783
+ unsigned PtrSize = Asm->getDataLayout ().getPointerSize ();
2784
+
2785
+ // Build a list of CUs used.
2786
+ std::vector<CompileUnit *> CUs;
2787
+ for (SpansType::iterator it = Spans.begin (); it != Spans.end (); it++) {
2788
+ CompileUnit *CU = it->first ;
2789
+ CUs.push_back (CU);
2790
+ }
2791
+
2792
+ // Sort the CU list (again, to ensure consistent output order).
2793
+ std::sort (CUs.begin (), CUs.end (), CUSort);
2794
+
2795
+ // Emit an arange table for each CU we used.
2796
+ for (size_t CUIdx=0 ;CUIdx<CUs.size ();CUIdx++) {
2797
+ CompileUnit *CU = CUs[CUIdx];
2798
+ std::vector<ArangeSpan> &List = Spans[CU];
2799
+
2800
+ // Emit size of content not including length itself.
2801
+ unsigned ContentSize
2802
+ = sizeof (int16_t ) // DWARF ARange version number
2803
+ + sizeof (int32_t ) // Offset of CU in the .debug_info section
2804
+ + sizeof (int8_t ) // Pointer Size (in bytes)
2805
+ + sizeof (int8_t ); // Segment Size (in bytes)
2806
+
2807
+ unsigned TupleSize = PtrSize * 2 ;
2808
+
2809
+ // 7.20 in the Dwarf specs requires the table to be aligned to a tuple.
2810
+ unsigned Padding = 0 ;
2811
+ while (((sizeof (int32_t ) + ContentSize + Padding) % TupleSize) != 0 )
2812
+ Padding++;
2813
+
2814
+ ContentSize += Padding;
2815
+ ContentSize += (List.size () + 1 ) * TupleSize;
2816
+
2817
+ // For each compile unit, write the list of spans it covers.
2818
+ Asm->OutStreamer .AddComment (" Length of ARange Set" );
2819
+ Asm->EmitInt32 (ContentSize);
2820
+ Asm->OutStreamer .AddComment (" DWARF Arange version number" );
2821
+ Asm->EmitInt16 (dwarf::DW_ARANGES_VERSION);
2822
+ Asm->OutStreamer .AddComment (" Offset Into Debug Info Section" );
2823
+ Asm->EmitSectionOffset (
2824
+ Asm->GetTempSymbol (ISec->getLabelBeginName (), CU->getUniqueID ()),
2825
+ DwarfInfoSectionSym);
2826
+ Asm->OutStreamer .AddComment (" Address Size (in bytes)" );
2827
+ Asm->EmitInt8 (PtrSize);
2828
+ Asm->OutStreamer .AddComment (" Segment Size (in bytes)" );
2829
+ Asm->EmitInt8 (0 );
2830
+
2831
+ for (unsigned n = 0 ; n < Padding; n++)
2832
+ Asm->EmitInt8 (0xff );
2833
+
2834
+ for (unsigned n = 0 ; n < List.size (); n++) {
2835
+ const ArangeSpan &Span = List[n];
2836
+ Asm->EmitLabelReference (Span.Start , PtrSize);
2837
+
2838
+ // Calculate the size as being from the span start to it's end.
2839
+ // If we have no valid end symbol, then we just cover the first byte.
2840
+ // (this sucks, but I can't seem to figure out how to get the size)
2841
+ if (Span.End )
2842
+ Asm->EmitLabelDifference (Span.End , Span.Start , PtrSize);
2843
+ else
2844
+ Asm->OutStreamer .EmitIntValue (1 , PtrSize);
2845
+ }
2846
+
2847
+ Asm->OutStreamer .AddComment (" ARange terminator" );
2848
+ Asm->OutStreamer .EmitIntValue (0 , PtrSize);
2849
+ Asm->OutStreamer .EmitIntValue (0 , PtrSize);
2850
+ }
2667
2851
}
2668
2852
2669
2853
// Emit visible names into a debug ranges section.
0 commit comments