r.Add = ofs
}
-func (c dwctxt) AddDWARFSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
+func (c dwctxt) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64) {
+ size := 4
+ if isDwarf64(c.linkctxt) {
+ size = 8
+ }
+
c.AddSectionOffset(s, size, t, ofs)
ls := s.(*sym.Symbol)
ls.R[len(ls.R)-1].Type = objabi.R_DWARFSECREF
panic("should be used only in the compiler")
}
+func isDwarf64(ctxt *Link) bool {
+ return ctxt.HeadType == objabi.Haix
+}
+
var gdbscript string
var dwarfp []*sym.Symbol
}
}
+// createUnitLength creates the initial length field with value v and update
+// offset of unit_length if needed.
+func createUnitLength(ctxt *Link, s *sym.Symbol, v uint64) {
+ if isDwarf64(ctxt) {
+ s.AddUint32(ctxt.Arch, 0xFFFFFFFF)
+ }
+ addDwarfAddrField(ctxt, s, v)
+}
+
+// addDwarfAddrField adds a DWARF field in DWARF 64bits or 32bits.
+func addDwarfAddrField(ctxt *Link, s *sym.Symbol, v uint64) {
+ if isDwarf64(ctxt) {
+ s.AddUint(ctxt.Arch, v)
+ } else {
+ s.AddUint32(ctxt.Arch, uint32(v))
+ }
+}
+
+// addDwarfAddrRef adds a DWARF pointer in DWARF 64bits or 32bits.
+func addDwarfAddrRef(ctxt *Link, s *sym.Symbol, t *sym.Symbol) {
+ if isDwarf64(ctxt) {
+ adddwarfref(ctxt, s, t, 8)
+ } else {
+ adddwarfref(ctxt, s, t, 4)
+ }
+}
+
// compilationUnit is per-compilation unit (equivalently, per-package)
// debug-related data.
type compilationUnit struct {
// Write .debug_line Line Number Program Header (sec 6.2.4)
// Fields marked with (*) must be changed for 64-bit dwarf
unitLengthOffset := ls.Size
- ls.AddUint32(ctxt.Arch, 0) // unit_length (*), filled in at end.
+ createUnitLength(ctxt, ls, 0) // unit_length (*), filled in at end
unitstart = ls.Size
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
headerLengthOffset := ls.Size
- ls.AddUint32(ctxt.Arch, 0) // header_length (*), filled in at end.
+ addDwarfAddrField(ctxt, ls, 0) // header_length (*), filled in at end
headerstart = ls.Size
// cpos == unitstart + 4 + 2 + 4
dwarf.Uleb128put(dwarfctxt, ls, 1)
ls.AddUint8(dwarf.DW_LNE_end_sequence)
- ls.SetUint32(ctxt.Arch, unitLengthOffset, uint32(ls.Size-unitstart))
- ls.SetUint32(ctxt.Arch, headerLengthOffset, uint32(headerend-headerstart))
+ if ctxt.HeadType == objabi.Haix {
+ saveDwsectCUSize(".debug_line", unit.lib.String(), uint64(ls.Size-unitLengthOffset))
+ }
+ if isDwarf64(ctxt) {
+ ls.SetUint(ctxt.Arch, unitLengthOffset+4, uint64(ls.Size-unitstart)) // +4 because of 0xFFFFFFFF
+ ls.SetUint(ctxt.Arch, headerLengthOffset, uint64(headerend-headerstart))
+ } else {
+ ls.SetUint32(ctxt.Arch, unitLengthOffset, uint32(ls.Size-unitstart))
+ ls.SetUint32(ctxt.Arch, headerLengthOffset, uint32(headerend-headerstart))
+ }
// Apply any R_DWARFFILEREF relocations, since we now know the
// line table file indices for this compilation unit. Note that
if haslinkregister(ctxt) {
cieReserve = 32
}
- fs.AddUint32(ctxt.Arch, cieReserve) // initial length, must be multiple of thearch.ptrsize
- fs.AddUint32(ctxt.Arch, 0xffffffff) // cid.
+ createUnitLength(ctxt, fs, uint64(cieReserve)) // initial length, must be multiple of thearch.ptrsize
+ addDwarfAddrField(ctxt, fs, 0xffffffff) // cid.
fs.AddUint8(3) // dwarf version (appendix F)
fs.AddUint8(0) // augmentation ""
dwarf.Uleb128put(dwarfctxt, fs, 1) // code_alignment_factor
// ptrsize: address range
fs.AddUint32(ctxt.Arch, uint32(4+2*ctxt.Arch.PtrSize+len(deltaBuf))) // length (excludes itself)
if ctxt.LinkMode == LinkExternal {
- adddwarfref(ctxt, fs, fs, 4)
+ addDwarfAddrRef(ctxt, fs, fs)
} else {
- fs.AddUint32(ctxt.Arch, 0) // CIE offset
+ addDwarfAddrField(ctxt, fs, 0) // CIE offset
}
fs.AddAddr(ctxt.Arch, s)
fs.AddUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range
// Write .debug_info Compilation Unit Header (sec 7.5.1)
// Fields marked with (*) must be changed for 64-bit dwarf
// This must match COMPUNITHEADERSIZE above.
- s.AddUint32(ctxt.Arch, 0) // unit_length (*), will be filled in later.
- s.AddUint16(ctxt.Arch, 4) // dwarf version (appendix F)
+ createUnitLength(ctxt, s, 0) // unit_length (*), will be filled in later.
+ s.AddUint16(ctxt.Arch, 4) // dwarf version (appendix F)
// debug_abbrev_offset (*)
- adddwarfref(ctxt, s, abbrevsym, 4)
+ addDwarfAddrRef(ctxt, s, abbrevsym)
s.AddUint8(uint8(ctxt.Arch.PtrSize)) // address_size
for _, child := range cu {
cusize += child.Size
}
- cusize -= 4 // exclude the length field.
- s.SetUint32(ctxt.Arch, 0, uint32(cusize))
+ // Save size for AIX symbol table.
+ if ctxt.HeadType == objabi.Haix {
+ saveDwsectCUSize(".debug_info", getPkgFromCUSym(s), uint64(cusize))
+ }
+ if isDwarf64(ctxt) {
+ cusize -= 12 // exclude the length field.
+ s.SetUint(ctxt.Arch, 4, uint64(cusize)) // 4 because of 0XFFFFFFFF
+ } else {
+ cusize -= 4 // exclude the length field.
+ s.SetUint32(ctxt.Arch, 0, uint32(cusize))
+ }
// Leave a breadcrumb for writepub. This does not
// appear in the DWARF output.
newattr(compunit, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, cusize, 0)
culength := uint32(getattr(compunit, dwarf.DW_AT_byte_size).Value) + 4
// Write .debug_pubnames/types Header (sec 6.1.1)
- s.AddUint32(ctxt.Arch, 0) // unit_length (*), will be filled in later.
- s.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
- adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4) // debug_info_offset (of the Comp unit Header)
- s.AddUint32(ctxt.Arch, culength) // debug_info_length
+ createUnitLength(ctxt, s, 0) // unit_length (*), will be filled in later.
+ s.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
+ addDwarfAddrRef(ctxt, s, dtolsym(compunit.Sym)) // debug_info_offset (of the Comp unit Header)
+ addDwarfAddrField(ctxt, s, uint64(culength)) // debug_info_length
for die := compunit.Child; die != nil; die = die.Link {
if !ispub(die) {
if die.Sym == nil {
fmt.Println("Missing sym for ", name)
}
- adddwarfref(ctxt, s, dtolsym(die.Sym), 4)
+ addDwarfAddrRef(ctxt, s, dtolsym(die.Sym))
Addstring(s, name)
}
- s.AddUint32(ctxt.Arch, 0)
+ addDwarfAddrField(ctxt, s, 0) // Null offset
- s.SetUint32(ctxt.Arch, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
+ // On AIX, save the current size of this compilation unit.
+ if ctxt.HeadType == objabi.Haix {
+ saveDwsectCUSize(sname, getPkgFromCUSym(dtolsym(compunit.Sym)), uint64(s.Size-sectionstart))
+ }
+ if isDwarf64(ctxt) {
+ s.SetUint(ctxt.Arch, sectionstart+4, uint64(s.Size-sectionstart)-12) // exclude the length field.
+ } else {
+ s.SetUint32(ctxt.Arch, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
+ }
}
return syms
}
func writegdbscript(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
+ // TODO (aix): make it available
+ if ctxt.HeadType == objabi.Haix {
+ return syms
+ }
if ctxt.LinkMode == LinkExternal && ctxt.HeadType == objabi.Hwindows && ctxt.BuildMode == BuildModeCArchive {
// gcc on Windows places .debug_gdb_scripts in the wrong location, which
// causes the program not to run. See https://golang.org/issue/20183
return v[i].lib.Textp[0].Value < v[j].lib.Textp[0].Value
}
}
+
+// On AIX, the symbol table needs to know where are the compilation units parts
+// for a specific package in each .dw section.
+// dwsectCUSize map will save the size of a compilation unit for
+// the corresponding .dw section.
+// This size can later be retrieved with the index "sectionName.pkgName".
+var dwsectCUSize map[string]uint64
+
+// getDwsectCUSize retrieves the corresponding package size inside the current section.
+func getDwsectCUSize(sname string, pkgname string) uint64 {
+ return dwsectCUSize[sname+"."+pkgname]
+}
+
+func saveDwsectCUSize(sname string, pkgname string, size uint64) {
+ dwsectCUSize[sname+"."+pkgname] = size
+}
+
+// getPkgFromCUSym returns the package name for the compilation unit
+// represented by s.
+// The prefix dwarf.InfoPrefix+".pkg." needs to be removed in order to get
+// the package name.
+func getPkgFromCUSym(s *sym.Symbol) string {
+ return strings.TrimPrefix(s.Name, dwarf.InfoPrefix+".pkg.")
+}