1
0
mirror of https://github.com/golang/go synced 2024-11-12 07:10:22 -07:00

Revert "cmd/internal/ld: put read-only relocated data into .data.rel.ro when making a shared object"

This reverts commit 2c2cbb69c8.

Broke darwin/arm64

Change-Id: Ibd2dea475d6ce6a8b4b40e2da19a83fc0514025d
Reviewed-on: https://go-review.googlesource.com/14301
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Dave Cheney 2015-09-04 09:53:35 +00:00 committed by Michael Hudson-Doyle
parent ced0646fe5
commit e49b2460a4
13 changed files with 18 additions and 206 deletions

View File

@ -81,13 +81,6 @@ GOPATH=$(pwd) go install -buildmode=c-shared $suffix libgo
GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo.$libext src/libgo/libgo.go
binpush libgo.$libext
if [ "$goos" == "linux" ]; then
if readelf -d libgo.$libext | grep TEXTREL >/dev/null; then
echo "libgo.$libext has TEXTREL set"
exit 1
fi
fi
# test0: exported symbols in shared lib are accessible.
# TODO(iant): using _shared here shouldn't really be necessary.
$(go env CC) $(go env GOGCCFLAGS) -I ${installdir} -o testp main0.c libgo.$libext

View File

@ -163,45 +163,6 @@ func TestSOBuilt(t *testing.T) {
}
}
func hasDynTag(f *elf.File, tag elf.DynTag) bool {
ds := f.SectionByType(elf.SHT_DYNAMIC)
if ds == nil {
return false
}
d, err := ds.Data()
if err != nil {
return false
}
for len(d) > 0 {
var t elf.DynTag
switch f.Class {
case elf.ELFCLASS32:
t = elf.DynTag(f.ByteOrder.Uint32(d[0:4]))
d = d[8:]
case elf.ELFCLASS64:
t = elf.DynTag(f.ByteOrder.Uint64(d[0:8]))
d = d[16:]
}
if t == tag {
return true
}
}
return false
}
// The shared library does not have relocations against the text segment.
func TestNoTextrel(t *testing.T) {
sopath := filepath.Join(gorootInstallDir, soname)
f, err := elf.Open(sopath)
if err != nil {
t.Fatal("elf.Open failed: ", err)
}
defer f.Close()
if hasDynTag(f, elf.DT_TEXTREL) {
t.Errorf("%s has DT_TEXTREL set", soname)
}
}
// The install command should have created a "shlibname" file for the
// listed packages (and runtime/cgo) indicating the name of the shared
// library containing it.

View File

@ -334,7 +334,6 @@ const (
Sxxx = iota
STEXT
SELFRXSECT
STYPE
SSTRING
SGOSTRING
@ -342,25 +341,6 @@ const (
SGCBITS
SRODATA
SFUNCTAB
// Types STYPE-SFUNCTAB above are written to the .rodata section by default.
// When linking a shared object, some conceptually "read only" types need to
// be written to by relocations and putting them in a section called
// ".rodata" interacts poorly with the system linkers. The GNU linkers
// support this situation by arranging for sections of the name
// ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after
// relocations have applied, so when the Go linker is creating a shared
// object it checks all objects of the above types and bumps any object that
// has a relocation to it to the corresponding type below, which are then
// written to sections with appropriate magic names.
STYPERELRO
SSTRINGRELRO
SGOSTRINGRELRO
SGOFUNCRELRO
SGCBITSRELRO
SRODATARELRO
SFUNCTABRELRO
STYPELINK
SSYMTAB
SPCLNTAB

View File

@ -1207,31 +1207,6 @@ func dodata() {
*l = nil
if UseRelro() {
// "read only" data with relocations needs to go in its own section
// when building a shared library. We do this by boosting objects of
// type SXXX with relocations to type SXXXRELRO.
for s := datap; s != nil; s = s.Next {
if (s.Type >= obj.STYPE && s.Type <= obj.SFUNCTAB && len(s.R) > 0) || s.Type == obj.SGOSTRING {
s.Type += (obj.STYPERELRO - obj.STYPE)
if s.Outer != nil {
s.Outer.Type = s.Type
}
}
}
// Check that we haven't made two symbols with the same .Outer into
// different types (because references two symbols with non-nil Outer
// become references to the outer symbol + offset it's vital that the
// symbol and the outer end up in the same section).
for s := datap; s != nil; s = s.Next {
if s.Outer != nil && s.Outer.Type != s.Type {
Diag("inconsistent types for %s and its Outer %s (%d != %d)",
s.Name, s.Outer.Name, s.Type, s.Outer.Type)
}
}
}
datap = listsort(datap, datcmp, listnextp)
if Iself {
@ -1490,12 +1465,12 @@ func dodata() {
/* read-only data */
sect = addsection(segro, ".rodata", 04)
sect.Align = maxalign(s, obj.STYPERELRO-1)
sect.Align = maxalign(s, obj.STYPELINK-1)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = 0
Linklookup(Ctxt, "runtime.rodata", 0).Sect = sect
Linklookup(Ctxt, "runtime.erodata", 0).Sect = sect
for ; s != nil && s.Type < obj.STYPERELRO; s = s.Next {
for ; s != nil && s.Type < obj.STYPELINK; s = s.Next {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Type = obj.SRODATA
@ -1505,45 +1480,8 @@ func dodata() {
sect.Length = uint64(datsize) - sect.Vaddr
// There is some data that are conceptually read-only but are written to by
// relocations. On GNU systems, we can arrange for the dynamic linker to
// mprotect sections after relocations are applied by giving them write
// permissions in the object file and calling them ".data.rel.ro.FOO". We
// divide the .rodata section between actual .rodata and .data.rel.ro.rodata,
// but for the other sections that this applies to, we just write a read-only
// .FOO section or a read-write .data.rel.ro.FOO section depending on the
// situation.
// TODO(mwhudson): It would make sense to do this more widely, but it makes
// the system linker segfault on darwin.
relro_perms := 04
relro_prefix := ""
if UseRelro() {
relro_perms = 06
relro_prefix = ".data.rel.ro"
/* data only written by relocations */
sect = addsection(segro, ".data.rel.ro", 06)
sect.Align = maxalign(s, obj.STYPELINK-1)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = 0
for ; s != nil && s.Type < obj.STYPELINK; s = s.Next {
datsize = aligndatsize(datsize, s)
if s.Outer != nil && s.Outer.Sect != nil && s.Outer.Sect != sect {
Diag("s.Outer (%s) in different section from s (%s)", s.Outer.Name, s.Name)
}
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
growdatsize(&datsize, s)
}
sect.Length = uint64(datsize) - sect.Vaddr
}
/* typelink */
sect = addsection(segro, relro_prefix+".typelink", relro_perms)
sect = addsection(segro, ".typelink", 04)
sect.Align = maxalign(s, obj.STYPELINK)
datsize = Rnd(datsize, int64(sect.Align))
@ -1561,7 +1499,7 @@ func dodata() {
sect.Length = uint64(datsize) - sect.Vaddr
/* gosymtab */
sect = addsection(segro, relro_prefix+".gosymtab", relro_perms)
sect = addsection(segro, ".gosymtab", 04)
sect.Align = maxalign(s, obj.SPCLNTAB-1)
datsize = Rnd(datsize, int64(sect.Align))
@ -1579,7 +1517,7 @@ func dodata() {
sect.Length = uint64(datsize) - sect.Vaddr
/* gopclntab */
sect = addsection(segro, relro_prefix+".gopclntab", relro_perms)
sect = addsection(segro, ".gopclntab", 04)
sect.Align = maxalign(s, obj.SELFROSECT-1)
datsize = Rnd(datsize, int64(sect.Align))
@ -1785,11 +1723,6 @@ func address() {
rodata = text.Next
}
typelink := rodata.Next
if UseRelro() {
// There is another section (.data.rel.ro) when building a shared
// object on elf systems.
typelink = typelink.Next
}
symtab := typelink.Next
pclntab := symtab.Next

View File

@ -1690,18 +1690,9 @@ func doelf() {
}
Addstring(shstrtab, ".elfdata")
Addstring(shstrtab, ".rodata")
if Buildmode == BuildmodeShared || Buildmode == BuildmodeCShared {
Addstring(shstrtab, ".data.rel.ro")
}
// See the comment about data.rel.ro.FOO section names in data.go.
relro_prefix := ""
if UseRelro() {
relro_prefix = ".data.rel.ro"
}
Addstring(shstrtab, relro_prefix+".typelink")
Addstring(shstrtab, relro_prefix+".gosymtab")
Addstring(shstrtab, relro_prefix+".gopclntab")
Addstring(shstrtab, ".typelink")
Addstring(shstrtab, ".gosymtab")
Addstring(shstrtab, ".gopclntab")
if Linkmode == LinkExternal {
Debug['d'] = 1
@ -1710,26 +1701,20 @@ func doelf() {
case '6', '7', '9':
Addstring(shstrtab, ".rela.text")
Addstring(shstrtab, ".rela.rodata")
Addstring(shstrtab, ".rela"+relro_prefix+".typelink")
Addstring(shstrtab, ".rela"+relro_prefix+".gosymtab")
Addstring(shstrtab, ".rela"+relro_prefix+".gopclntab")
Addstring(shstrtab, ".rela.typelink")
Addstring(shstrtab, ".rela.gosymtab")
Addstring(shstrtab, ".rela.gopclntab")
Addstring(shstrtab, ".rela.noptrdata")
Addstring(shstrtab, ".rela.data")
if UseRelro() {
Addstring(shstrtab, ".rela.data.rel.ro")
}
default:
Addstring(shstrtab, ".rel.text")
Addstring(shstrtab, ".rel.rodata")
Addstring(shstrtab, ".rel"+relro_prefix+".typelink")
Addstring(shstrtab, ".rel"+relro_prefix+".gosymtab")
Addstring(shstrtab, ".rel"+relro_prefix+".gopclntab")
Addstring(shstrtab, ".rel.typelink")
Addstring(shstrtab, ".rel.gosymtab")
Addstring(shstrtab, ".rel.gopclntab")
Addstring(shstrtab, ".rel.noptrdata")
Addstring(shstrtab, ".rel.data")
if UseRelro() {
Addstring(shstrtab, ".rel.data.rel.ro")
}
}
// add a .note.GNU-stack section to mark the stack as non-executable

View File

@ -174,12 +174,6 @@ func DynlinkingGo() bool {
return Buildmode == BuildmodeShared || Linkshared
}
// UseRelro returns whether to make use of "read only relocations" aka
// relro.
func UseRelro() bool {
return (Buildmode == BuildmodeCShared || Buildmode == BuildmodeShared) && Iself
}
var (
Thestring string
Thelinkarch *LinkArch
@ -986,9 +980,6 @@ func hostlink() {
argv = append(argv, "-dynamiclib")
} else {
argv = append(argv, "-Wl,-Bsymbolic")
if UseRelro() {
argv = append(argv, "-Wl,-z,relro")
}
argv = append(argv, "-shared")
}
case BuildmodeShared:
@ -1000,10 +991,7 @@ func hostlink() {
// think we may well end up wanting to use -Bsymbolic here
// anyway.
argv = append(argv, "-Wl,-Bsymbolic-functions")
if UseRelro() {
argv = append(argv, "-shared")
}
argv = append(argv, "-Wl,-z,relro")
argv = append(argv, "-shared")
}
if Linkshared && Iself {
@ -1783,12 +1771,6 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
obj.SGOSTRING,
obj.SGOFUNC,
obj.SGCBITS,
obj.STYPERELRO,
obj.SSTRINGRELRO,
obj.SGOSTRINGRELRO,
obj.SGOFUNCRELRO,
obj.SGCBITSRELRO,
obj.SRODATARELRO,
obj.SWINDOWS:
if !s.Reachable {
continue

View File

@ -350,29 +350,13 @@ func symtab() {
// pseudo-symbols to mark locations of type, string, and go string data.
var symtype *LSym
var symtyperel *LSym
if UseRelro() && Buildmode == BuildmodeCShared {
if !DynlinkingGo() {
s = Linklookup(Ctxt, "type.*", 0)
s.Type = obj.STYPE
s.Size = 0
s.Reachable = true
symtype = s
s = Linklookup(Ctxt, "typerel.*", 0)
s.Type = obj.STYPERELRO
s.Size = 0
s.Reachable = true
symtyperel = s
} else if !DynlinkingGo() {
s = Linklookup(Ctxt, "type.*", 0)
s.Type = obj.STYPE
s.Size = 0
s.Reachable = true
symtype = s
symtyperel = s
}
s = Linklookup(Ctxt, "go.string.*", 0)
@ -397,7 +381,6 @@ func symtab() {
symgcbits := s
symtypelink := Linklookup(Ctxt, "runtime.typelink", 0)
symtypelink.Type = obj.STYPELINK
symt = Linklookup(Ctxt, "runtime.symtab", 0)
symt.Local = true
@ -417,14 +400,9 @@ func symtab() {
}
if strings.HasPrefix(s.Name, "type.") && !DynlinkingGo() {
s.Type = obj.STYPE
s.Hide = 1
if UseRelro() && len(s.R) > 0 {
s.Type = obj.STYPERELRO
s.Outer = symtyperel
} else {
s.Type = obj.STYPE
s.Outer = symtype
}
s.Outer = symtype
}
if strings.HasPrefix(s.Name, "go.typelink.") {

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.