@@ -67,7 +67,12 @@ func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
6767 r .Add = ofs
6868}
6969
70- func (c dwctxt ) AddDWARFSectionOffset (s dwarf.Sym , size int , t interface {}, ofs int64 ) {
70+ func (c dwctxt ) AddDWARFAddrSectionOffset (s dwarf.Sym , t interface {}, ofs int64 ) {
71+ size := 4
72+ if isDwarf64 (c .linkctxt ) {
73+ size = 8
74+ }
75+
7176 c .AddSectionOffset (s , size , t , ofs )
7277 ls := s .(* sym.Symbol )
7378 ls .R [len (ls .R )- 1 ].Type = objabi .R_DWARFSECREF
@@ -95,6 +100,10 @@ func (c dwctxt) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets []
95100 panic ("should be used only in the compiler" )
96101}
97102
103+ func isDwarf64 (ctxt * Link ) bool {
104+ return ctxt .HeadType == objabi .Haix
105+ }
106+
98107var gdbscript string
99108
100109var dwarfp []* sym.Symbol
@@ -873,6 +882,33 @@ func defdwsymb(ctxt *Link, s *sym.Symbol, str string, t SymbolType, v int64, got
873882 }
874883}
875884
885+ // createUnitLength creates the initial length field with value v and update
886+ // offset of unit_length if needed.
887+ func createUnitLength (ctxt * Link , s * sym.Symbol , v uint64 ) {
888+ if isDwarf64 (ctxt ) {
889+ s .AddUint32 (ctxt .Arch , 0xFFFFFFFF )
890+ }
891+ addDwarfAddrField (ctxt , s , v )
892+ }
893+
894+ // addDwarfAddrField adds a DWARF field in DWARF 64bits or 32bits.
895+ func addDwarfAddrField (ctxt * Link , s * sym.Symbol , v uint64 ) {
896+ if isDwarf64 (ctxt ) {
897+ s .AddUint (ctxt .Arch , v )
898+ } else {
899+ s .AddUint32 (ctxt .Arch , uint32 (v ))
900+ }
901+ }
902+
903+ // addDwarfAddrRef adds a DWARF pointer in DWARF 64bits or 32bits.
904+ func addDwarfAddrRef (ctxt * Link , s * sym.Symbol , t * sym.Symbol ) {
905+ if isDwarf64 (ctxt ) {
906+ adddwarfref (ctxt , s , t , 8 )
907+ } else {
908+ adddwarfref (ctxt , s , t , 4 )
909+ }
910+ }
911+
876912// compilationUnit is per-compilation unit (equivalently, per-package)
877913// debug-related data.
878914type compilationUnit struct {
@@ -1081,11 +1117,11 @@ func writelines(ctxt *Link, unit *compilationUnit, ls *sym.Symbol) {
10811117 // Write .debug_line Line Number Program Header (sec 6.2.4)
10821118 // Fields marked with (*) must be changed for 64-bit dwarf
10831119 unitLengthOffset := ls .Size
1084- ls . AddUint32 (ctxt . Arch , 0 ) // unit_length (*), filled in at end.
1120+ createUnitLength (ctxt , ls , 0 ) // unit_length (*), filled in at end
10851121 unitstart = ls .Size
10861122 ls .AddUint16 (ctxt .Arch , 2 ) // dwarf version (appendix F) -- version 3 is incompatible w/ XCode 9.0's dsymutil, latest supported on OSX 10.12 as of 2018-05
10871123 headerLengthOffset := ls .Size
1088- ls . AddUint32 (ctxt . Arch , 0 ) // header_length (*), filled in at end.
1124+ addDwarfAddrField (ctxt , ls , 0 ) // header_length (*), filled in at end
10891125 headerstart = ls .Size
10901126
10911127 // cpos == unitstart + 4 + 2 + 4
@@ -1238,8 +1274,16 @@ func writelines(ctxt *Link, unit *compilationUnit, ls *sym.Symbol) {
12381274 dwarf .Uleb128put (dwarfctxt , ls , 1 )
12391275 ls .AddUint8 (dwarf .DW_LNE_end_sequence )
12401276
1241- ls .SetUint32 (ctxt .Arch , unitLengthOffset , uint32 (ls .Size - unitstart ))
1242- ls .SetUint32 (ctxt .Arch , headerLengthOffset , uint32 (headerend - headerstart ))
1277+ if ctxt .HeadType == objabi .Haix {
1278+ saveDwsectCUSize (".debug_line" , unit .lib .String (), uint64 (ls .Size - unitLengthOffset ))
1279+ }
1280+ if isDwarf64 (ctxt ) {
1281+ ls .SetUint (ctxt .Arch , unitLengthOffset + 4 , uint64 (ls .Size - unitstart )) // +4 because of 0xFFFFFFFF
1282+ ls .SetUint (ctxt .Arch , headerLengthOffset , uint64 (headerend - headerstart ))
1283+ } else {
1284+ ls .SetUint32 (ctxt .Arch , unitLengthOffset , uint32 (ls .Size - unitstart ))
1285+ ls .SetUint32 (ctxt .Arch , headerLengthOffset , uint32 (headerend - headerstart ))
1286+ }
12431287
12441288 // Apply any R_DWARFFILEREF relocations, since we now know the
12451289 // line table file indices for this compilation unit. Note that
@@ -1329,8 +1373,8 @@ func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
13291373 if haslinkregister (ctxt ) {
13301374 cieReserve = 32
13311375 }
1332- fs . AddUint32 (ctxt . Arch , cieReserve ) // initial length, must be multiple of thearch.ptrsize
1333- fs . AddUint32 (ctxt . Arch , 0xffffffff ) // cid.
1376+ createUnitLength (ctxt , fs , uint64 ( cieReserve )) // initial length, must be multiple of thearch.ptrsize
1377+ addDwarfAddrField (ctxt , fs , 0xffffffff ) // cid.
13341378 fs .AddUint8 (3 ) // dwarf version (appendix F)
13351379 fs .AddUint8 (0 ) // augmentation ""
13361380 dwarf .Uleb128put (dwarfctxt , fs , 1 ) // code_alignment_factor
@@ -1418,9 +1462,9 @@ func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
14181462 // ptrsize: address range
14191463 fs .AddUint32 (ctxt .Arch , uint32 (4 + 2 * ctxt .Arch .PtrSize + len (deltaBuf ))) // length (excludes itself)
14201464 if ctxt .LinkMode == LinkExternal {
1421- adddwarfref (ctxt , fs , fs , 4 )
1465+ addDwarfAddrRef (ctxt , fs , fs )
14221466 } else {
1423- fs . AddUint32 (ctxt . Arch , 0 ) // CIE offset
1467+ addDwarfAddrField (ctxt , fs , 0 ) // CIE offset
14241468 }
14251469 fs .AddAddr (ctxt .Arch , s )
14261470 fs .AddUintXX (ctxt .Arch , uint64 (s .Size ), ctxt .Arch .PtrSize ) // address range
@@ -1455,11 +1499,11 @@ func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevs
14551499 // Write .debug_info Compilation Unit Header (sec 7.5.1)
14561500 // Fields marked with (*) must be changed for 64-bit dwarf
14571501 // This must match COMPUNITHEADERSIZE above.
1458- s . AddUint32 (ctxt . Arch , 0 ) // unit_length (*), will be filled in later.
1459- s .AddUint16 (ctxt .Arch , 4 ) // dwarf version (appendix F)
1502+ createUnitLength (ctxt , s , 0 ) // unit_length (*), will be filled in later.
1503+ s .AddUint16 (ctxt .Arch , 4 ) // dwarf version (appendix F)
14601504
14611505 // debug_abbrev_offset (*)
1462- adddwarfref (ctxt , s , abbrevsym , 4 )
1506+ addDwarfAddrRef (ctxt , s , abbrevsym )
14631507
14641508 s .AddUint8 (uint8 (ctxt .Arch .PtrSize )) // address_size
14651509
@@ -1477,8 +1521,17 @@ func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit, abbrevs
14771521 for _ , child := range cu {
14781522 cusize += child .Size
14791523 }
1480- cusize -= 4 // exclude the length field.
1481- s .SetUint32 (ctxt .Arch , 0 , uint32 (cusize ))
1524+ // Save size for AIX symbol table.
1525+ if ctxt .HeadType == objabi .Haix {
1526+ saveDwsectCUSize (".debug_info" , getPkgFromCUSym (s ), uint64 (cusize ))
1527+ }
1528+ if isDwarf64 (ctxt ) {
1529+ cusize -= 12 // exclude the length field.
1530+ s .SetUint (ctxt .Arch , 4 , uint64 (cusize )) // 4 because of 0XFFFFFFFF
1531+ } else {
1532+ cusize -= 4 // exclude the length field.
1533+ s .SetUint32 (ctxt .Arch , 0 , uint32 (cusize ))
1534+ }
14821535 // Leave a breadcrumb for writepub. This does not
14831536 // appear in the DWARF output.
14841537 newattr (compunit , dwarf .DW_AT_byte_size , dwarf .DW_CLS_CONSTANT , cusize , 0 )
@@ -1519,10 +1572,10 @@ func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*s
15191572 culength := uint32 (getattr (compunit , dwarf .DW_AT_byte_size ).Value ) + 4
15201573
15211574 // Write .debug_pubnames/types Header (sec 6.1.1)
1522- s . AddUint32 (ctxt . Arch , 0 ) // unit_length (*), will be filled in later.
1523- s .AddUint16 (ctxt .Arch , 2 ) // dwarf version (appendix F)
1524- adddwarfref (ctxt , s , dtolsym (compunit .Sym ), 4 ) // debug_info_offset (of the Comp unit Header)
1525- s . AddUint32 (ctxt . Arch , culength ) // debug_info_length
1575+ createUnitLength (ctxt , s , 0 ) // unit_length (*), will be filled in later.
1576+ s .AddUint16 (ctxt .Arch , 2 ) // dwarf version (appendix F)
1577+ addDwarfAddrRef (ctxt , s , dtolsym (compunit .Sym )) // debug_info_offset (of the Comp unit Header)
1578+ addDwarfAddrField (ctxt , s , uint64 ( culength )) // debug_info_length
15261579
15271580 for die := compunit .Child ; die != nil ; die = die .Link {
15281581 if ! ispub (die ) {
@@ -1533,19 +1586,31 @@ func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*s
15331586 if die .Sym == nil {
15341587 fmt .Println ("Missing sym for " , name )
15351588 }
1536- adddwarfref (ctxt , s , dtolsym (die .Sym ), 4 )
1589+ addDwarfAddrRef (ctxt , s , dtolsym (die .Sym ))
15371590 Addstring (s , name )
15381591 }
15391592
1540- s . AddUint32 (ctxt . Arch , 0 )
1593+ addDwarfAddrField (ctxt , s , 0 ) // Null offset
15411594
1542- s .SetUint32 (ctxt .Arch , sectionstart , uint32 (s .Size - sectionstart )- 4 ) // exclude the length field.
1595+ // On AIX, save the current size of this compilation unit.
1596+ if ctxt .HeadType == objabi .Haix {
1597+ saveDwsectCUSize (sname , getPkgFromCUSym (dtolsym (compunit .Sym )), uint64 (s .Size - sectionstart ))
1598+ }
1599+ if isDwarf64 (ctxt ) {
1600+ s .SetUint (ctxt .Arch , sectionstart + 4 , uint64 (s .Size - sectionstart )- 12 ) // exclude the length field.
1601+ } else {
1602+ s .SetUint32 (ctxt .Arch , sectionstart , uint32 (s .Size - sectionstart )- 4 ) // exclude the length field.
1603+ }
15431604 }
15441605
15451606 return syms
15461607}
15471608
15481609func writegdbscript (ctxt * Link , syms []* sym.Symbol ) []* sym.Symbol {
1610+ // TODO (aix): make it available
1611+ if ctxt .HeadType == objabi .Haix {
1612+ return syms
1613+ }
15491614 if ctxt .LinkMode == LinkExternal && ctxt .HeadType == objabi .Hwindows && ctxt .BuildMode == BuildModeCArchive {
15501615 // gcc on Windows places .debug_gdb_scripts in the wrong location, which
15511616 // causes the program not to run. See https://golang.org/issue/20183
@@ -2019,3 +2084,27 @@ func (v compilationUnitByStartPC) Less(i, j int) bool {
20192084 return v [i ].lib .Textp [0 ].Value < v [j ].lib .Textp [0 ].Value
20202085 }
20212086}
2087+
2088+ // On AIX, the symbol table needs to know where are the compilation units parts
2089+ // for a specific package in each .dw section.
2090+ // dwsectCUSize map will save the size of a compilation unit for
2091+ // the corresponding .dw section.
2092+ // This size can later be retrieved with the index "sectionName.pkgName".
2093+ var dwsectCUSize map [string ]uint64
2094+
2095+ // getDwsectCUSize retrieves the corresponding package size inside the current section.
2096+ func getDwsectCUSize (sname string , pkgname string ) uint64 {
2097+ return dwsectCUSize [sname + "." + pkgname ]
2098+ }
2099+
2100+ func saveDwsectCUSize (sname string , pkgname string , size uint64 ) {
2101+ dwsectCUSize [sname + "." + pkgname ] = size
2102+ }
2103+
2104+ // getPkgFromCUSym returns the package name for the compilation unit
2105+ // represented by s.
2106+ // The prefix dwarf.InfoPrefix+".pkg." needs to be removed in order to get
2107+ // the package name.
2108+ func getPkgFromCUSym (s * sym.Symbol ) string {
2109+ return strings .TrimPrefix (s .Name , dwarf .InfoPrefix + ".pkg." )
2110+ }
0 commit comments