Commit 79688ca5 authored by Michel Lespinasse's avatar Michel Lespinasse

cmd/link: collect itablinks as a slice in moduledata

See #14874

This change tells the linker to collect all the itablink symbols and
collect them so that moduledata can have a slice of all compiler
generated itabs.

The logic is shamelessly adapted from what is done with typelink symbols.

Change-Id: Ie93b59acf0fcba908a876d506afbf796f222dbac
Reviewed-on: https://go-review.googlesource.com/20889Reviewed-by: 's avatarKeith Randall <khr@golang.org>
parent f00bbd5f
...@@ -43,6 +43,7 @@ const ( ...@@ -43,6 +43,7 @@ const (
SRODATA SymKind = obj.SRODATA SRODATA SymKind = obj.SRODATA
SFUNCTAB SymKind = obj.SFUNCTAB SFUNCTAB SymKind = obj.SFUNCTAB
STYPELINK SymKind = obj.STYPELINK STYPELINK SymKind = obj.STYPELINK
SITABLINK SymKind = obj.SITABLINK
SSYMTAB SymKind = obj.SSYMTAB // TODO: move to unmapped section SSYMTAB SymKind = obj.SSYMTAB // TODO: move to unmapped section
SPCLNTAB SymKind = obj.SPCLNTAB SPCLNTAB SymKind = obj.SPCLNTAB
SELFROSECT SymKind = obj.SELFROSECT SELFROSECT SymKind = obj.SELFROSECT
...@@ -106,6 +107,7 @@ var symKindStrings = []string{ ...@@ -106,6 +107,7 @@ var symKindStrings = []string{
STLSBSS: "STLSBSS", STLSBSS: "STLSBSS",
STYPE: "STYPE", STYPE: "STYPE",
STYPELINK: "STYPELINK", STYPELINK: "STYPELINK",
SITABLINK: "SITABLINK",
SWINDOWS: "SWINDOWS", SWINDOWS: "SWINDOWS",
SXREF: "SXREF", SXREF: "SXREF",
} }
......
...@@ -397,6 +397,7 @@ const ( ...@@ -397,6 +397,7 @@ const (
SFUNCTABRELRO SFUNCTABRELRO
STYPELINK STYPELINK
SITABLINK
SSYMTAB SSYMTAB
SPCLNTAB SPCLNTAB
SELFROSECT SELFROSECT
......
...@@ -41,7 +41,7 @@ func (f *goobjFile) symbols() ([]Sym, error) { ...@@ -41,7 +41,7 @@ func (f *goobjFile) symbols() ([]Sym, error) {
switch s.Kind { switch s.Kind {
case goobj.STEXT, goobj.SELFRXSECT: case goobj.STEXT, goobj.SELFRXSECT:
sym.Code = 'T' sym.Code = 'T'
case goobj.STYPE, goobj.SSTRING, goobj.SGOSTRING, goobj.SGOFUNC, goobj.SRODATA, goobj.SFUNCTAB, goobj.STYPELINK, goobj.SSYMTAB, goobj.SPCLNTAB, goobj.SELFROSECT: case goobj.STYPE, goobj.SSTRING, goobj.SGOSTRING, goobj.SGOFUNC, goobj.SRODATA, goobj.SFUNCTAB, goobj.STYPELINK, goobj.SITABLINK, goobj.SSYMTAB, goobj.SPCLNTAB, goobj.SELFROSECT:
sym.Code = 'R' sym.Code = 'R'
case goobj.SMACHOPLT, goobj.SELFSECT, goobj.SMACHO, goobj.SMACHOGOT, goobj.SNOPTRDATA, goobj.SINITARR, goobj.SDATA, goobj.SWINDOWS: case goobj.SMACHOPLT, goobj.SELFSECT, goobj.SMACHO, goobj.SMACHOGOT, goobj.SNOPTRDATA, goobj.SINITARR, goobj.SDATA, goobj.SWINDOWS:
sym.Code = 'D' sym.Code = 'D'
......
...@@ -1605,6 +1605,24 @@ func dodata() { ...@@ -1605,6 +1605,24 @@ func dodata() {
sect.Length = uint64(datsize) - sect.Vaddr sect.Length = uint64(datsize) - sect.Vaddr
/* itablink */
sect = addsection(segro, relro_prefix+".itablink", relro_perms)
sect.Align = maxalign(s, obj.SITABLINK)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
Linklookup(Ctxt, "runtime.itablink", 0).Sect = sect
Linklookup(Ctxt, "runtime.eitablink", 0).Sect = sect
for ; s != nil && s.Type == obj.SITABLINK; s = s.Next {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
growdatsize(&datsize, s)
}
sect.Length = uint64(datsize) - sect.Vaddr
/* gosymtab */ /* gosymtab */
sect = addsection(segro, relro_prefix+".gosymtab", relro_perms) sect = addsection(segro, relro_prefix+".gosymtab", relro_perms)
...@@ -1835,7 +1853,8 @@ func address() { ...@@ -1835,7 +1853,8 @@ func address() {
// object on elf systems. // object on elf systems.
typelink = typelink.Next typelink = typelink.Next
} }
symtab := typelink.Next itablink := typelink.Next
symtab := itablink.Next
pclntab := symtab.Next pclntab := symtab.Next
var sub *LSym var sub *LSym
...@@ -1862,6 +1881,8 @@ func address() { ...@@ -1862,6 +1881,8 @@ func address() {
xdefine("runtime.erodata", obj.SRODATA, int64(rodata.Vaddr+rodata.Length)) xdefine("runtime.erodata", obj.SRODATA, int64(rodata.Vaddr+rodata.Length))
xdefine("runtime.typelink", obj.SRODATA, int64(typelink.Vaddr)) xdefine("runtime.typelink", obj.SRODATA, int64(typelink.Vaddr))
xdefine("runtime.etypelink", obj.SRODATA, int64(typelink.Vaddr+typelink.Length)) xdefine("runtime.etypelink", obj.SRODATA, int64(typelink.Vaddr+typelink.Length))
xdefine("runtime.itablink", obj.SRODATA, int64(itablink.Vaddr))
xdefine("runtime.eitablink", obj.SRODATA, int64(itablink.Vaddr+itablink.Length))
sym := Linklookup(Ctxt, "runtime.gcdata", 0) sym := Linklookup(Ctxt, "runtime.gcdata", 0)
sym.Attr |= AttrLocal sym.Attr |= AttrLocal
......
...@@ -107,10 +107,11 @@ func deadcode(ctxt *Link) { ...@@ -107,10 +107,11 @@ func deadcode(ctxt *Link) {
} }
if Buildmode != BuildmodeShared { if Buildmode != BuildmodeShared {
// Keep a typelink if the symbol it points at is being kept. // Keep a typelink or itablink if the symbol it points at is being kept.
// (When BuildmodeShared, always keep typelinks.) // (When BuildmodeShared, always keep typelinks and itablinks.)
for _, s := range ctxt.Allsym { for _, s := range ctxt.Allsym {
if strings.HasPrefix(s.Name, "go.typelink.") { if strings.HasPrefix(s.Name, "go.typelink.") ||
strings.HasPrefix(s.Name, "go.itablink.") {
s.Attr.Set(AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable()) s.Attr.Set(AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
} }
} }
......
...@@ -1740,6 +1740,7 @@ func doelf() { ...@@ -1740,6 +1740,7 @@ func doelf() {
relro_prefix = ".data.rel.ro" relro_prefix = ".data.rel.ro"
} }
Addstring(shstrtab, relro_prefix+".typelink") Addstring(shstrtab, relro_prefix+".typelink")
Addstring(shstrtab, relro_prefix+".itablink")
Addstring(shstrtab, relro_prefix+".gosymtab") Addstring(shstrtab, relro_prefix+".gosymtab")
Addstring(shstrtab, relro_prefix+".gopclntab") Addstring(shstrtab, relro_prefix+".gopclntab")
...@@ -1751,6 +1752,7 @@ func doelf() { ...@@ -1751,6 +1752,7 @@ func doelf() {
Addstring(shstrtab, ".rela.text") Addstring(shstrtab, ".rela.text")
Addstring(shstrtab, ".rela.rodata") Addstring(shstrtab, ".rela.rodata")
Addstring(shstrtab, ".rela"+relro_prefix+".typelink") Addstring(shstrtab, ".rela"+relro_prefix+".typelink")
Addstring(shstrtab, ".rela"+relro_prefix+".itablink")
Addstring(shstrtab, ".rela"+relro_prefix+".gosymtab") Addstring(shstrtab, ".rela"+relro_prefix+".gosymtab")
Addstring(shstrtab, ".rela"+relro_prefix+".gopclntab") Addstring(shstrtab, ".rela"+relro_prefix+".gopclntab")
Addstring(shstrtab, ".rela.noptrdata") Addstring(shstrtab, ".rela.noptrdata")
...@@ -1763,6 +1765,7 @@ func doelf() { ...@@ -1763,6 +1765,7 @@ func doelf() {
Addstring(shstrtab, ".rel.text") Addstring(shstrtab, ".rel.text")
Addstring(shstrtab, ".rel.rodata") Addstring(shstrtab, ".rel.rodata")
Addstring(shstrtab, ".rel"+relro_prefix+".typelink") Addstring(shstrtab, ".rel"+relro_prefix+".typelink")
Addstring(shstrtab, ".rel"+relro_prefix+".itablink")
Addstring(shstrtab, ".rel"+relro_prefix+".gosymtab") Addstring(shstrtab, ".rel"+relro_prefix+".gosymtab")
Addstring(shstrtab, ".rel"+relro_prefix+".gopclntab") Addstring(shstrtab, ".rel"+relro_prefix+".gopclntab")
Addstring(shstrtab, ".rel.noptrdata") Addstring(shstrtab, ".rel.noptrdata")
......
...@@ -1930,6 +1930,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) { ...@@ -1930,6 +1930,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
obj.SGCBITSRELRO, obj.SGCBITSRELRO,
obj.SRODATARELRO, obj.SRODATARELRO,
obj.STYPELINK, obj.STYPELINK,
obj.SITABLINK,
obj.SWINDOWS: obj.SWINDOWS:
if !s.Attr.Reachable() { if !s.Attr.Reachable() {
continue continue
......
...@@ -342,6 +342,8 @@ func symtab() { ...@@ -342,6 +342,8 @@ func symtab() {
xdefine("runtime.etext", obj.STEXT, 0) xdefine("runtime.etext", obj.STEXT, 0)
xdefine("runtime.typelink", obj.SRODATA, 0) xdefine("runtime.typelink", obj.SRODATA, 0)
xdefine("runtime.etypelink", obj.SRODATA, 0) xdefine("runtime.etypelink", obj.SRODATA, 0)
xdefine("runtime.itablink", obj.SRODATA, 0)
xdefine("runtime.eitablink", obj.SRODATA, 0)
xdefine("runtime.rodata", obj.SRODATA, 0) xdefine("runtime.rodata", obj.SRODATA, 0)
xdefine("runtime.erodata", obj.SRODATA, 0) xdefine("runtime.erodata", obj.SRODATA, 0)
xdefine("runtime.noptrdata", obj.SNOPTRDATA, 0) xdefine("runtime.noptrdata", obj.SNOPTRDATA, 0)
...@@ -428,6 +430,9 @@ func symtab() { ...@@ -428,6 +430,9 @@ func symtab() {
symtypelink := Linklookup(Ctxt, "runtime.typelink", 0) symtypelink := Linklookup(Ctxt, "runtime.typelink", 0)
symtypelink.Type = obj.STYPELINK symtypelink.Type = obj.STYPELINK
symitablink := Linklookup(Ctxt, "runtime.itablink", 0)
symitablink.Type = obj.SITABLINK
symt = Linklookup(Ctxt, "runtime.symtab", 0) symt = Linklookup(Ctxt, "runtime.symtab", 0)
symt.Attr |= AttrLocal symt.Attr |= AttrLocal
symt.Type = obj.SSYMTAB symt.Type = obj.SSYMTAB
...@@ -435,6 +440,7 @@ func symtab() { ...@@ -435,6 +440,7 @@ func symtab() {
symt.Attr |= AttrReachable symt.Attr |= AttrReachable
ntypelinks := 0 ntypelinks := 0
nitablinks := 0
// assign specific types so that they sort together. // assign specific types so that they sort together.
// within a type they sort by size, so the .* symbols // within a type they sort by size, so the .* symbols
...@@ -463,6 +469,13 @@ func symtab() { ...@@ -463,6 +469,13 @@ func symtab() {
s.Outer = symtypelink s.Outer = symtypelink
} }
if strings.HasPrefix(s.Name, "go.itablink.") {
nitablinks++
s.Type = obj.SITABLINK
s.Attr |= AttrHidden
s.Outer = symitablink
}
if strings.HasPrefix(s.Name, "go.string.") { if strings.HasPrefix(s.Name, "go.string.") {
s.Type = obj.SGOSTRING s.Type = obj.SGOSTRING
s.Attr |= AttrHidden s.Attr |= AttrHidden
...@@ -543,6 +556,10 @@ func symtab() { ...@@ -543,6 +556,10 @@ func symtab() {
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.typelink", 0)) Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.typelink", 0))
adduint(Ctxt, moduledata, uint64(ntypelinks)) adduint(Ctxt, moduledata, uint64(ntypelinks))
adduint(Ctxt, moduledata, uint64(ntypelinks)) adduint(Ctxt, moduledata, uint64(ntypelinks))
// The itablinks slice
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.itablink", 0))
adduint(Ctxt, moduledata, uint64(nitablinks))
adduint(Ctxt, moduledata, uint64(nitablinks))
if len(Ctxt.Shlibs) > 0 { if len(Ctxt.Shlibs) > 0 {
thismodulename := filepath.Base(outfile) thismodulename := filepath.Base(outfile)
switch Buildmode { switch Buildmode {
......
...@@ -129,6 +129,7 @@ type moduledata struct { ...@@ -129,6 +129,7 @@ type moduledata struct {
end, gcdata, gcbss uintptr end, gcdata, gcbss uintptr
typelinks []*_type typelinks []*_type
itablinks []*itab
modulename string modulename string
modulehashes []modulehash modulehashes []modulehash
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment