aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/link/internal/ld/pcln.go34
-rw-r--r--src/cmd/link/internal/ld/symtab.go1
-rw-r--r--src/cmd/link/internal/ld/xcoff.go12
-rw-r--r--src/cmd/link/link_test.go93
-rw-r--r--src/cmd/nm/nm_test.go5
5 files changed, 83 insertions, 62 deletions
diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go
index 1eb7112e64..08c4d4db83 100644
--- a/src/cmd/link/internal/ld/pcln.go
+++ b/src/cmd/link/internal/ld/pcln.go
@@ -55,13 +55,20 @@ type pclntab struct {
// 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
}
@@ -277,7 +284,7 @@ func (state *pclntab) generatePCHeader(ctxt *Link) {
}
}
- 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
@@ -326,7 +333,7 @@ func (state *pclntab) generateFuncnametab(ctxt *Link, funcs []loader.Sym) map[lo
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
}
@@ -442,7 +449,7 @@ func (state *pclntab) generateFilenameTabs(ctxt *Link, compUnits []*sym.Compilat
}
}
}
- 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) {
@@ -454,7 +461,7 @@ func (state *pclntab) generateFilenameTabs(ctxt *Link, compUnits []*sym.Compilat
}
}
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
}
@@ -518,7 +525,7 @@ func (state *pclntab) generatePctab(ctxt *Link, funcs []loader.Sym) {
}
}
- 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.
@@ -647,7 +654,7 @@ func (state *pclntab) generateFuncdata(ctxt *Link, funcs []loader.Sym, inlsyms m
}
}
- 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.
@@ -703,7 +710,7 @@ func (state *pclntab) generateFunctab(ctxt *Link, funcs []loader.Sym, inlSyms ma
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.
@@ -967,6 +974,10 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
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)
@@ -1076,6 +1087,7 @@ func (ctxt *Link) findfunctab(state *pclntab, container loader.Bitmap) {
}
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)
}
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index f9bc7007ed..dd2d74895a 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -672,6 +672,7 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
addRef("runtime.rodata")
addRef("runtime.erodata")
addRef("runtime.epclntab")
+ addRef("go:func.*")
// As we use relative addressing for text symbols in functab, it is
// important that the offsets we computed stay unchanged by the external
// linker, i.e. all symbols in Textp should not be removed.
diff --git a/src/cmd/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go
index 77ae1236c9..5f01eb2507 100644
--- a/src/cmd/link/internal/ld/xcoff.go
+++ b/src/cmd/link/internal/ld/xcoff.go
@@ -603,14 +603,20 @@ func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) {
outerSymSize["go:string.*"] = size
case sym.SGOFUNC:
if !ctxt.DynlinkingGo() {
- outerSymSize["go:func.*"] = size
+ outerSymSize["go:funcdesc"] = size
}
case sym.SGOFUNCRELRO:
- outerSymSize["go:funcrel.*"] = size
+ outerSymSize["go:funcdescrel"] = size
case sym.SGCBITS:
outerSymSize["runtime.gcbits.*"] = size
case sym.SPCLNTAB:
- outerSymSize["runtime.pclntab"] = size
+ // go:func.* size must be removed from pclntab,
+ // as it's a real symbol. Same for runtime.findfunctab.
+ fsize := ldr.SymSize(ldr.Lookup("go:func.*", 0))
+ fft := ldr.Lookup("runtime.findfunctab", 0)
+ fsize = Rnd(fsize, int64(symalign(ldr, fft)))
+ tsize := ldr.SymSize(fft)
+ outerSymSize["runtime.pclntab"] = size - (fsize + tsize)
}
}
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 0c4cde0399..bc7504e5b1 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -1960,34 +1960,56 @@ func TestFuncdataPlacement(t *testing.T) {
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")
}
@@ -2183,31 +2205,16 @@ func TestModuledataPlacement(t *testing.T) {
}
}
- 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
- }
- }
}
}
diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go
index f740a3f738..424ac72e22 100644
--- a/src/cmd/nm/nm_test.go
+++ b/src/cmd/nm/nm_test.go
@@ -118,11 +118,6 @@ func testGoExec(t *testing.T, iscgo, isexternallinker bool) {
"runtime.noptrdata": "D",
}
- if runtime.GOOS == "aix" && iscgo {
- // pclntab is moved to .data section on AIX.
- runtimeSyms["runtime.epclntab"] = "D"
- }
-
out, err = testenv.Command(t, testenv.Executable(t), exe).CombinedOutput()
if err != nil {
t.Fatalf("go tool nm: %v\n%s", err, string(out))