// addGeneratedSym adds a generator symbol to pclntab, returning the new Sym.
// It is the caller's responsibility to save the symbol in state.
-func (state *pclntab) addGeneratedSym(ctxt *Link, name string, size int64, f generatorFunc) loader.Sym {
+func (state *pclntab) addGeneratedSym(ctxt *Link, name string, size int64, align int32, f generatorFunc) loader.Sym {
size = Rnd(size, int64(ctxt.Arch.PtrSize))
state.size += size
s := ctxt.createGeneratorSymbol(name, 0, sym.SPCLNTAB, size, f)
- ctxt.loader.SetAttrReachable(s, true)
- ctxt.loader.SetCarrierSym(s, state.carrier)
- ctxt.loader.SetAttrNotInSymbolTable(s, true)
+ ldr := ctxt.loader
+ ldr.SetSymAlign(s, align)
+ ldr.SetAttrReachable(s, true)
+ ldr.SetCarrierSym(s, state.carrier)
+ ldr.SetAttrNotInSymbolTable(s, true)
+
+ if align > ldr.SymAlign(state.carrier) {
+ ldr.SetSymAlign(state.carrier, align)
+ }
+
return s
}
}
}
- state.pcheader = state.addGeneratedSym(ctxt, "runtime.pcheader", size, writeHeader)
+ state.pcheader = state.addGeneratedSym(ctxt, "runtime.pcheader", size, int32(ctxt.Arch.PtrSize), writeHeader)
}
// walkFuncs iterates over the funcs, calling a function for each unique
size += int64(len(ctxt.loader.SymName(s)) + 1) // NULL terminate
})
- state.funcnametab = state.addGeneratedSym(ctxt, "runtime.funcnametab", size, writeFuncNameTab)
+ state.funcnametab = state.addGeneratedSym(ctxt, "runtime.funcnametab", size, 1, writeFuncNameTab)
return nameOffsets
}
}
}
}
- state.cutab = state.addGeneratedSym(ctxt, "runtime.cutab", int64(totalEntries*4), writeCutab)
+ state.cutab = state.addGeneratedSym(ctxt, "runtime.cutab", int64(totalEntries*4), 4, writeCutab)
// Write filetab.
writeFiletab := func(ctxt *Link, s loader.Sym) {
}
}
state.nfiles = uint32(len(fileOffsets))
- state.filetab = state.addGeneratedSym(ctxt, "runtime.filetab", fileSize, writeFiletab)
+ state.filetab = state.addGeneratedSym(ctxt, "runtime.filetab", fileSize, 1, writeFiletab)
return cuOffsets
}
}
}
- state.pctab = state.addGeneratedSym(ctxt, "runtime.pctab", size, writePctab)
+ state.pctab = state.addGeneratedSym(ctxt, "runtime.pctab", size, 1, writePctab)
}
// generateFuncdata writes out the funcdata information.
}
}
- state.funcdata = state.addGeneratedSym(ctxt, "go:func.*", size, writeFuncData)
+ state.funcdata = state.addGeneratedSym(ctxt, "go:func.*", size, maxAlign, writeFuncData)
// Because the funcdata previously was not in pclntab,
// we need to keep the visible symbol so that tools can find it.
writePCToFunc(ctxt, sb, funcs, startLocations)
writeFuncs(ctxt, sb, funcs, inlSyms, startLocations, cuOffsets, nameOffsets)
}
- state.pclntab = state.addGeneratedSym(ctxt, "runtime.functab", size, writePcln)
+ state.pclntab = state.addGeneratedSym(ctxt, "runtime.functab", size, 4, writePcln)
}
// funcData returns the funcdata and offsets for the FuncInfo.
ldr.SetAttrReachable(state.carrier, true)
setCarrierSym(sym.SPCLNTAB, state.carrier)
+ // Aign pclntab to at least a pointer boundary,
+ // for pcHeader. This may be raised further by subsymbols.
+ ldr.SetSymAlign(state.carrier, int32(ctxt.Arch.PtrSize))
+
state.generatePCHeader(ctxt)
nameOffsets := state.generateFuncnametab(ctxt, funcs)
cuOffsets := state.generateFilenameTabs(ctxt, compUnits, funcs)
}
state.findfunctab = ctxt.createGeneratorSymbol("runtime.findfunctab", 0, sym.SPCLNTAB, size, writeFindFuncTab)
+ ldr.SetSymAlign(state.findfunctab, 4)
ldr.SetAttrReachable(state.findfunctab, true)
ldr.SetAttrLocal(state.findfunctab, true)
}
case xf != nil:
defer xf.Close()
+ var moddataSym, gofuncSym, pclntabSym, epclntabSym *xcoff.Symbol
for _, sym := range xf.Symbols {
switch sym.Name {
case moddataSymName:
- moddataAddr = sym.Value
+ moddataSym = sym
case gofuncSymName:
- gofuncAddr = sym.Value
+ gofuncSym = sym
+ case "runtime.pclntab":
+ pclntabSym = sym
+ case "runtime.epclntab":
+ epclntabSym = sym
}
}
- for _, sec := range xf.Sections {
- if sec.Name == ".go.pclntab" {
- data, err := sec.Data()
- if err != nil {
- t.Fatal(err)
- }
- pclntab = data
- pclntabAddr = sec.VirtualAddress
- pclntabEnd = sec.VirtualAddress + sec.Size
- }
- if moddataAddr >= sec.VirtualAddress && moddataAddr < sec.VirtualAddress+sec.Size {
- data, err := sec.Data()
- if err != nil {
- t.Fatal(err)
- }
- moddataBytes = data[moddataAddr-sec.VirtualAddress:]
- }
+ if moddataSym == nil {
+ t.Fatalf("could not find symbol %s", moddataSymName)
+ }
+ if gofuncSym == nil {
+ t.Fatalf("could not find symbol %s", gofuncSymName)
+ }
+ if pclntabSym == nil {
+ t.Fatal("could not find symbol runtime.pclntab")
+ }
+ if epclntabSym == nil {
+ t.Fatal("could not find symbol runtime.epclntab")
}
+ sec := xf.Sections[moddataSym.SectionNumber-1]
+ data, err := sec.Data()
+ if err != nil {
+ t.Fatal(err)
+ }
+ moddataBytes = data[moddataSym.Value:]
+ moddataAddr = uint64(sec.VirtualAddress + moddataSym.Value)
+
+ sec = xf.Sections[gofuncSym.SectionNumber-1]
+ gofuncAddr = uint64(sec.VirtualAddress + gofuncSym.Value)
+
+ if pclntabSym.SectionNumber != epclntabSym.SectionNumber {
+ t.Fatalf("runtime.pclntab section %d != runtime.epclntab section %d", pclntabSym.SectionNumber, epclntabSym.SectionNumber)
+ }
+ sec = xf.Sections[pclntabSym.SectionNumber-1]
+ data, err = sec.Data()
+ if err != nil {
+ t.Fatal(err)
+ }
+ pclntab = data[pclntabSym.Value:epclntabSym.Value]
+ pclntabAddr = uint64(sec.VirtualAddress + pclntabSym.Value)
+ pclntabEnd = uint64(sec.VirtualAddress + epclntabSym.Value)
+
default:
panic("can't happen")
}
}
}
- case pf != nil:
- defer pf.Close()
+ case pf != nil, xf != nil:
+ if pf != nil {
+ defer pf.Close()
+ }
+ if xf != nil {
+ defer xf.Close()
+ }
- // On Windows all the Go specific sections seem to
- // get stuffed into a few Windows sections,
+ // On Windows and AIX all the Go specific sections
+ // get stuffed into a few sections,
// so there is nothing to test here.
-
- case xf != nil:
- defer xf.Close()
-
- for _, sym := range xf.Symbols {
- if sym.Name == moddataSymName {
- if sym.SectionNumber == 0 {
- t.Errorf("moduledata not in a section")
- } else {
- sec := xf.Sections[sym.SectionNumber-1]
- if sec.Name != ".go.module" {
- t.Errorf("moduledata in section %s, not .go.module", sec.Name)
- }
- if sym.Value != sec.VirtualAddress {
- t.Errorf("moduledata address %#x != section start address %#x", sym.Value, sec.VirtualAddress)
- }
- }
- break
- }
- }
}
}