@@ -264,15 +264,6 @@ func newrefattr(die *dwarf.DWDie, attr uint16, ref *sym.Symbol) *dwarf.DWAttr {
264
264
return newattr (die , attr , dwarf .DW_CLS_REFERENCE , 0 , ref )
265
265
}
266
266
267
- func putdies (linkctxt * Link , ctxt dwarf.Context , syms []* sym.Symbol , die * dwarf.DWDie ) []* sym.Symbol {
268
- for ; die != nil ; die = die .Link {
269
- syms = putdie (linkctxt , ctxt , syms , die )
270
- }
271
- syms [len (syms )- 1 ].AddUint8 (0 )
272
-
273
- return syms
274
- }
275
-
276
267
func dtolsym (s dwarf.Sym ) * sym.Symbol {
277
268
if s == nil {
278
269
return nil
@@ -294,7 +285,10 @@ func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.D
294
285
dwarf .Uleb128put (ctxt , s , int64 (die .Abbrev ))
295
286
dwarf .PutAttrs (ctxt , s , die .Abbrev , die .Attr )
296
287
if dwarf .HasChildren (die ) {
297
- return putdies (linkctxt , ctxt , syms , die .Child )
288
+ for die := die .Child ; die != nil ; die = die .Link {
289
+ syms = putdie (linkctxt , ctxt , syms , die )
290
+ }
291
+ syms [len (syms )- 1 ].AddUint8 (0 )
298
292
}
299
293
return syms
300
294
}
@@ -1517,7 +1511,7 @@ const (
1517
1511
COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
1518
1512
)
1519
1513
1520
- func writeinfo (ctxt * Link , syms []* sym.Symbol , units []* compilationUnit , abbrevsym * sym.Symbol ) []* sym.Symbol {
1514
+ func writeinfo (ctxt * Link , syms []* sym.Symbol , units []* compilationUnit , abbrevsym * sym.Symbol , pubNames , pubTypes * pubWriter ) []* sym.Symbol {
1521
1515
infosec := ctxt .Syms .Lookup (".debug_info" , 0 )
1522
1516
infosec .Type = sym .SDWARFINFO
1523
1517
infosec .Attr |= sym .AttrReachable
@@ -1533,6 +1527,9 @@ func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevs
1533
1527
continue
1534
1528
}
1535
1529
1530
+ pubNames .beginCompUnit (compunit )
1531
+ pubTypes .beginCompUnit (compunit )
1532
+
1536
1533
// Write .debug_info Compilation Unit Header (sec 7.5.1)
1537
1534
// Fields marked with (*) must be changed for 64-bit dwarf
1538
1535
// This must match COMPUNITHEADERSIZE above.
@@ -1553,11 +1550,32 @@ func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevs
1553
1550
if u .consts != nil {
1554
1551
cu = append (cu , u .consts )
1555
1552
}
1556
- cu = putdies (ctxt , dwarfctxt , cu , compunit .Child )
1557
1553
var cusize int64
1558
1554
for _ , child := range cu {
1559
1555
cusize += child .Size
1560
1556
}
1557
+
1558
+ for die := compunit .Child ; die != nil ; die = die .Link {
1559
+ l := len (cu )
1560
+ lastSymSz := cu [l - 1 ].Size
1561
+ cu = putdie (ctxt , dwarfctxt , cu , die )
1562
+ if ispubname (die ) {
1563
+ pubNames .add (die , cusize )
1564
+ }
1565
+ if ispubtype (die ) {
1566
+ pubTypes .add (die , cusize )
1567
+ }
1568
+ if lastSymSz != cu [l - 1 ].Size {
1569
+ // putdie will sometimes append directly to the last symbol of the list
1570
+ cusize = cusize - lastSymSz + cu [l - 1 ].Size
1571
+ }
1572
+ for _ , child := range cu [l :] {
1573
+ cusize += child .Size
1574
+ }
1575
+ }
1576
+ cu [len (cu )- 1 ].AddUint8 (0 ) // closes compilation unit DIE
1577
+ cusize ++
1578
+
1561
1579
// Save size for AIX symbol table.
1562
1580
if ctxt .HeadType == objabi .Haix {
1563
1581
saveDwsectCUSize (".debug_info" , getPkgFromCUSym (s ), uint64 (cusize ))
@@ -1569,9 +1587,8 @@ func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevs
1569
1587
cusize -= 4 // exclude the length field.
1570
1588
s .SetUint32 (ctxt .Arch , 0 , uint32 (cusize ))
1571
1589
}
1572
- // Leave a breadcrumb for writepub. This does not
1573
- // appear in the DWARF output.
1574
- newattr (compunit , dwarf .DW_AT_byte_size , dwarf .DW_CLS_CONSTANT , cusize , 0 )
1590
+ pubNames .endCompUnit (compunit , uint32 (cusize )+ 4 )
1591
+ pubTypes .endCompUnit (compunit , uint32 (cusize )+ 4 )
1575
1592
syms = append (syms , cu ... )
1576
1593
}
1577
1594
return syms
@@ -1595,52 +1612,57 @@ func ispubtype(die *dwarf.DWDie) bool {
1595
1612
return die .Abbrev >= dwarf .DW_ABRV_NULLTYPE
1596
1613
}
1597
1614
1598
- func writepub (ctxt * Link , sname string , ispub func (* dwarf.DWDie ) bool , syms []* sym.Symbol ) []* sym.Symbol {
1615
+ type pubWriter struct {
1616
+ ctxt * Link
1617
+ s * sym.Symbol
1618
+ sname string
1619
+
1620
+ sectionstart int64
1621
+ culengthOff int64
1622
+ }
1623
+
1624
+ func newPubWriter (ctxt * Link , sname string ) * pubWriter {
1599
1625
s := ctxt .Syms .Lookup (sname , 0 )
1600
1626
s .Type = sym .SDWARFSECT
1601
- syms = append (syms , s )
1602
-
1603
- for _ , u := range ctxt .compUnits {
1604
- if len (u .lib .Textp ) == 0 && u .dwinfo .Child == nil {
1605
- continue
1606
- }
1607
- compunit := u .dwinfo
1608
- sectionstart := s .Size
1609
- culength := uint32 (getattr (compunit , dwarf .DW_AT_byte_size ).Value ) + 4
1627
+ return & pubWriter {ctxt : ctxt , s : s , sname : sname }
1628
+ }
1610
1629
1611
- // Write .debug_pubnames/types Header (sec 6.1.1)
1612
- createUnitLength (ctxt , s , 0 ) // unit_length (*), will be filled in later.
1613
- s .AddUint16 (ctxt .Arch , 2 ) // dwarf version (appendix F)
1614
- addDwarfAddrRef (ctxt , s , dtolsym (compunit .Sym )) // debug_info_offset (of the Comp unit Header)
1615
- addDwarfAddrField (ctxt , s , uint64 (culength )) // debug_info_length
1630
+ func (pw * pubWriter ) beginCompUnit (compunit * dwarf.DWDie ) {
1631
+ pw .sectionstart = pw .s .Size
1616
1632
1617
- for die := compunit .Child ; die != nil ; die = die .Link {
1618
- if ! ispub (die ) {
1619
- continue
1620
- }
1621
- dwa := getattr (die , dwarf .DW_AT_name )
1622
- name := dwa .Data .(string )
1623
- if die .Sym == nil {
1624
- fmt .Println ("Missing sym for " , name )
1625
- }
1626
- addDwarfAddrRef (ctxt , s , dtolsym (die .Sym ))
1627
- Addstring (s , name )
1628
- }
1633
+ // Write .debug_pubnames/types Header (sec 6.1.1)
1634
+ createUnitLength (pw .ctxt , pw .s , 0 ) // unit_length (*), will be filled in later.
1635
+ pw .s .AddUint16 (pw .ctxt .Arch , 2 ) // dwarf version (appendix F)
1636
+ addDwarfAddrRef (pw .ctxt , pw .s , dtolsym (compunit .Sym )) // debug_info_offset (of the Comp unit Header)
1637
+ pw .culengthOff = pw .s .Size
1638
+ addDwarfAddrField (pw .ctxt , pw .s , uint64 (0 )) // debug_info_length, will be filled in later.
1629
1639
1630
- addDwarfAddrField ( ctxt , s , 0 ) // Null offset
1640
+ }
1631
1641
1632
- // On AIX, save the current size of this compilation unit.
1633
- if ctxt .HeadType == objabi .Haix {
1634
- saveDwsectCUSize (sname , getPkgFromCUSym (dtolsym (compunit .Sym )), uint64 (s .Size - sectionstart ))
1635
- }
1636
- if isDwarf64 (ctxt ) {
1637
- s .SetUint (ctxt .Arch , sectionstart + 4 , uint64 (s .Size - sectionstart )- 12 ) // exclude the length field.
1638
- } else {
1639
- s .SetUint32 (ctxt .Arch , sectionstart , uint32 (s .Size - sectionstart )- 4 ) // exclude the length field.
1640
- }
1642
+ func (pw * pubWriter ) add (die * dwarf.DWDie , offset int64 ) {
1643
+ dwa := getattr (die , dwarf .DW_AT_name )
1644
+ name := dwa .Data .(string )
1645
+ if die .Sym == nil {
1646
+ fmt .Println ("Missing sym for " , name )
1641
1647
}
1648
+ addDwarfAddrField (pw .ctxt , pw .s , uint64 (offset ))
1649
+ Addstring (pw .s , name )
1650
+ }
1642
1651
1643
- return syms
1652
+ func (pw * pubWriter ) endCompUnit (compunit * dwarf.DWDie , culength uint32 ) {
1653
+ addDwarfAddrField (pw .ctxt , pw .s , 0 ) // Null offset
1654
+
1655
+ // On AIX, save the current size of this compilation unit.
1656
+ if pw .ctxt .HeadType == objabi .Haix {
1657
+ saveDwsectCUSize (pw .sname , getPkgFromCUSym (dtolsym (compunit .Sym )), uint64 (pw .s .Size - pw .sectionstart ))
1658
+ }
1659
+ if isDwarf64 (pw .ctxt ) {
1660
+ pw .s .SetUint (pw .ctxt .Arch , pw .sectionstart + 4 , uint64 (pw .s .Size - pw .sectionstart )- 12 ) // exclude the length field.
1661
+ pw .s .SetUint (pw .ctxt .Arch , pw .culengthOff , uint64 (culength ))
1662
+ } else {
1663
+ pw .s .SetUint32 (pw .ctxt .Arch , pw .sectionstart , uint32 (pw .s .Size - pw .sectionstart )- 4 ) // exclude the length field.
1664
+ pw .s .SetUint32 (pw .ctxt .Arch , pw .culengthOff , culength )
1665
+ }
1644
1666
}
1645
1667
1646
1668
func writegdbscript (ctxt * Link , syms []* sym.Symbol ) []* sym.Symbol {
@@ -1878,13 +1900,14 @@ func dwarfGenerateDebugSyms(ctxt *Link) {
1878
1900
reversetree (& dwtypes .Child )
1879
1901
movetomodule (ctxt , & dwtypes )
1880
1902
1903
+ pubNames := newPubWriter (ctxt , ".debug_pubnames" )
1904
+ pubTypes := newPubWriter (ctxt , ".debug_pubtypes" )
1905
+
1881
1906
// Need to reorder symbols so sym.SDWARFINFO is after all sym.SDWARFSECT
1882
- // (but we need to generate dies before writepub)
1883
- infosyms := writeinfo (ctxt , nil , ctxt .compUnits , abbrev )
1907
+ infosyms := writeinfo (ctxt , nil , ctxt .compUnits , abbrev , pubNames , pubTypes )
1884
1908
1885
1909
syms = writeframes (ctxt , syms )
1886
- syms = writepub (ctxt , ".debug_pubnames" , ispubname , syms )
1887
- syms = writepub (ctxt , ".debug_pubtypes" , ispubtype , syms )
1910
+ syms = append (syms , pubNames .s , pubTypes .s )
1888
1911
syms = writegdbscript (ctxt , syms )
1889
1912
// Now we're done writing SDWARFSECT symbols, so we can write
1890
1913
// other SDWARF* symbols.
0 commit comments