mirror of
https://github.com/golang/go.git
synced 2024-09-22 10:58:58 +00:00
cmd/internal/ld: put read-only relocated data into .data.rel.ro when making a shared object
Currently Go produces shared libraries that cannot be shared between processes because they have relocations against the text segment (not text section). This fixes this by moving some data to sections with magic names recognized by the static linker. Fixes #10914 Updates #9210 Change-Id: I7178daadc0ae87953d5a084aa3d580f4e3b46d47 Reviewed-on: https://go-review.googlesource.com/10300 Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
eaea5ade2b
commit
2c2cbb69c8
@ -81,6 +81,13 @@ GOPATH=$(pwd) go install -buildmode=c-shared $suffix libgo
|
|||||||
GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo.$libext src/libgo/libgo.go
|
GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo.$libext src/libgo/libgo.go
|
||||||
binpush libgo.$libext
|
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.
|
# test0: exported symbols in shared lib are accessible.
|
||||||
# TODO(iant): using _shared here shouldn't really be necessary.
|
# TODO(iant): using _shared here shouldn't really be necessary.
|
||||||
$(go env CC) $(go env GOGCCFLAGS) -I ${installdir} -o testp main0.c libgo.$libext
|
$(go env CC) $(go env GOGCCFLAGS) -I ${installdir} -o testp main0.c libgo.$libext
|
||||||
|
@ -163,6 +163,45 @@ 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
|
// The install command should have created a "shlibname" file for the
|
||||||
// listed packages (and runtime/cgo) indicating the name of the shared
|
// listed packages (and runtime/cgo) indicating the name of the shared
|
||||||
// library containing it.
|
// library containing it.
|
||||||
|
@ -334,6 +334,7 @@ const (
|
|||||||
Sxxx = iota
|
Sxxx = iota
|
||||||
STEXT
|
STEXT
|
||||||
SELFRXSECT
|
SELFRXSECT
|
||||||
|
|
||||||
STYPE
|
STYPE
|
||||||
SSTRING
|
SSTRING
|
||||||
SGOSTRING
|
SGOSTRING
|
||||||
@ -341,6 +342,25 @@ const (
|
|||||||
SGCBITS
|
SGCBITS
|
||||||
SRODATA
|
SRODATA
|
||||||
SFUNCTAB
|
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
|
STYPELINK
|
||||||
SSYMTAB
|
SSYMTAB
|
||||||
SPCLNTAB
|
SPCLNTAB
|
||||||
|
@ -1207,6 +1207,31 @@ func dodata() {
|
|||||||
|
|
||||||
*l = nil
|
*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)
|
datap = listsort(datap, datcmp, listnextp)
|
||||||
|
|
||||||
if Iself {
|
if Iself {
|
||||||
@ -1465,12 +1490,12 @@ func dodata() {
|
|||||||
/* read-only data */
|
/* read-only data */
|
||||||
sect = addsection(segro, ".rodata", 04)
|
sect = addsection(segro, ".rodata", 04)
|
||||||
|
|
||||||
sect.Align = maxalign(s, obj.STYPELINK-1)
|
sect.Align = maxalign(s, obj.STYPERELRO-1)
|
||||||
datsize = Rnd(datsize, int64(sect.Align))
|
datsize = Rnd(datsize, int64(sect.Align))
|
||||||
sect.Vaddr = 0
|
sect.Vaddr = 0
|
||||||
Linklookup(Ctxt, "runtime.rodata", 0).Sect = sect
|
Linklookup(Ctxt, "runtime.rodata", 0).Sect = sect
|
||||||
Linklookup(Ctxt, "runtime.erodata", 0).Sect = sect
|
Linklookup(Ctxt, "runtime.erodata", 0).Sect = sect
|
||||||
for ; s != nil && s.Type < obj.STYPELINK; s = s.Next {
|
for ; s != nil && s.Type < obj.STYPERELRO; s = s.Next {
|
||||||
datsize = aligndatsize(datsize, s)
|
datsize = aligndatsize(datsize, s)
|
||||||
s.Sect = sect
|
s.Sect = sect
|
||||||
s.Type = obj.SRODATA
|
s.Type = obj.SRODATA
|
||||||
@ -1480,8 +1505,45 @@ func dodata() {
|
|||||||
|
|
||||||
sect.Length = uint64(datsize) - sect.Vaddr
|
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 */
|
/* typelink */
|
||||||
sect = addsection(segro, ".typelink", 04)
|
sect = addsection(segro, relro_prefix+".typelink", relro_perms)
|
||||||
|
|
||||||
sect.Align = maxalign(s, obj.STYPELINK)
|
sect.Align = maxalign(s, obj.STYPELINK)
|
||||||
datsize = Rnd(datsize, int64(sect.Align))
|
datsize = Rnd(datsize, int64(sect.Align))
|
||||||
@ -1499,7 +1561,7 @@ func dodata() {
|
|||||||
sect.Length = uint64(datsize) - sect.Vaddr
|
sect.Length = uint64(datsize) - sect.Vaddr
|
||||||
|
|
||||||
/* gosymtab */
|
/* gosymtab */
|
||||||
sect = addsection(segro, ".gosymtab", 04)
|
sect = addsection(segro, relro_prefix+".gosymtab", relro_perms)
|
||||||
|
|
||||||
sect.Align = maxalign(s, obj.SPCLNTAB-1)
|
sect.Align = maxalign(s, obj.SPCLNTAB-1)
|
||||||
datsize = Rnd(datsize, int64(sect.Align))
|
datsize = Rnd(datsize, int64(sect.Align))
|
||||||
@ -1517,7 +1579,7 @@ func dodata() {
|
|||||||
sect.Length = uint64(datsize) - sect.Vaddr
|
sect.Length = uint64(datsize) - sect.Vaddr
|
||||||
|
|
||||||
/* gopclntab */
|
/* gopclntab */
|
||||||
sect = addsection(segro, ".gopclntab", 04)
|
sect = addsection(segro, relro_prefix+".gopclntab", relro_perms)
|
||||||
|
|
||||||
sect.Align = maxalign(s, obj.SELFROSECT-1)
|
sect.Align = maxalign(s, obj.SELFROSECT-1)
|
||||||
datsize = Rnd(datsize, int64(sect.Align))
|
datsize = Rnd(datsize, int64(sect.Align))
|
||||||
@ -1723,6 +1785,11 @@ func address() {
|
|||||||
rodata = text.Next
|
rodata = text.Next
|
||||||
}
|
}
|
||||||
typelink := rodata.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
|
symtab := typelink.Next
|
||||||
pclntab := symtab.Next
|
pclntab := symtab.Next
|
||||||
|
|
||||||
|
@ -1690,9 +1690,18 @@ func doelf() {
|
|||||||
}
|
}
|
||||||
Addstring(shstrtab, ".elfdata")
|
Addstring(shstrtab, ".elfdata")
|
||||||
Addstring(shstrtab, ".rodata")
|
Addstring(shstrtab, ".rodata")
|
||||||
Addstring(shstrtab, ".typelink")
|
if Buildmode == BuildmodeShared || Buildmode == BuildmodeCShared {
|
||||||
Addstring(shstrtab, ".gosymtab")
|
Addstring(shstrtab, ".data.rel.ro")
|
||||||
Addstring(shstrtab, ".gopclntab")
|
}
|
||||||
|
// 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")
|
||||||
|
|
||||||
if Linkmode == LinkExternal {
|
if Linkmode == LinkExternal {
|
||||||
Debug['d'] = 1
|
Debug['d'] = 1
|
||||||
@ -1701,20 +1710,26 @@ func doelf() {
|
|||||||
case '6', '7', '9':
|
case '6', '7', '9':
|
||||||
Addstring(shstrtab, ".rela.text")
|
Addstring(shstrtab, ".rela.text")
|
||||||
Addstring(shstrtab, ".rela.rodata")
|
Addstring(shstrtab, ".rela.rodata")
|
||||||
Addstring(shstrtab, ".rela.typelink")
|
Addstring(shstrtab, ".rela"+relro_prefix+".typelink")
|
||||||
Addstring(shstrtab, ".rela.gosymtab")
|
Addstring(shstrtab, ".rela"+relro_prefix+".gosymtab")
|
||||||
Addstring(shstrtab, ".rela.gopclntab")
|
Addstring(shstrtab, ".rela"+relro_prefix+".gopclntab")
|
||||||
Addstring(shstrtab, ".rela.noptrdata")
|
Addstring(shstrtab, ".rela.noptrdata")
|
||||||
Addstring(shstrtab, ".rela.data")
|
Addstring(shstrtab, ".rela.data")
|
||||||
|
if UseRelro() {
|
||||||
|
Addstring(shstrtab, ".rela.data.rel.ro")
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Addstring(shstrtab, ".rel.text")
|
Addstring(shstrtab, ".rel.text")
|
||||||
Addstring(shstrtab, ".rel.rodata")
|
Addstring(shstrtab, ".rel.rodata")
|
||||||
Addstring(shstrtab, ".rel.typelink")
|
Addstring(shstrtab, ".rel"+relro_prefix+".typelink")
|
||||||
Addstring(shstrtab, ".rel.gosymtab")
|
Addstring(shstrtab, ".rel"+relro_prefix+".gosymtab")
|
||||||
Addstring(shstrtab, ".rel.gopclntab")
|
Addstring(shstrtab, ".rel"+relro_prefix+".gopclntab")
|
||||||
Addstring(shstrtab, ".rel.noptrdata")
|
Addstring(shstrtab, ".rel.noptrdata")
|
||||||
Addstring(shstrtab, ".rel.data")
|
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
|
// add a .note.GNU-stack section to mark the stack as non-executable
|
||||||
|
@ -174,6 +174,12 @@ func DynlinkingGo() bool {
|
|||||||
return Buildmode == BuildmodeShared || Linkshared
|
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 (
|
var (
|
||||||
Thestring string
|
Thestring string
|
||||||
Thelinkarch *LinkArch
|
Thelinkarch *LinkArch
|
||||||
@ -980,6 +986,9 @@ func hostlink() {
|
|||||||
argv = append(argv, "-dynamiclib")
|
argv = append(argv, "-dynamiclib")
|
||||||
} else {
|
} else {
|
||||||
argv = append(argv, "-Wl,-Bsymbolic")
|
argv = append(argv, "-Wl,-Bsymbolic")
|
||||||
|
if UseRelro() {
|
||||||
|
argv = append(argv, "-Wl,-z,relro")
|
||||||
|
}
|
||||||
argv = append(argv, "-shared")
|
argv = append(argv, "-shared")
|
||||||
}
|
}
|
||||||
case BuildmodeShared:
|
case BuildmodeShared:
|
||||||
@ -991,8 +1000,11 @@ func hostlink() {
|
|||||||
// think we may well end up wanting to use -Bsymbolic here
|
// think we may well end up wanting to use -Bsymbolic here
|
||||||
// anyway.
|
// anyway.
|
||||||
argv = append(argv, "-Wl,-Bsymbolic-functions")
|
argv = append(argv, "-Wl,-Bsymbolic-functions")
|
||||||
|
if UseRelro() {
|
||||||
argv = append(argv, "-shared")
|
argv = append(argv, "-shared")
|
||||||
}
|
}
|
||||||
|
argv = append(argv, "-Wl,-z,relro")
|
||||||
|
}
|
||||||
|
|
||||||
if Linkshared && Iself {
|
if Linkshared && Iself {
|
||||||
// We force all symbol resolution to be done at program startup
|
// We force all symbol resolution to be done at program startup
|
||||||
@ -1771,6 +1783,12 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
|||||||
obj.SGOSTRING,
|
obj.SGOSTRING,
|
||||||
obj.SGOFUNC,
|
obj.SGOFUNC,
|
||||||
obj.SGCBITS,
|
obj.SGCBITS,
|
||||||
|
obj.STYPERELRO,
|
||||||
|
obj.SSTRINGRELRO,
|
||||||
|
obj.SGOSTRINGRELRO,
|
||||||
|
obj.SGOFUNCRELRO,
|
||||||
|
obj.SGCBITSRELRO,
|
||||||
|
obj.SRODATARELRO,
|
||||||
obj.SWINDOWS:
|
obj.SWINDOWS:
|
||||||
if !s.Reachable {
|
if !s.Reachable {
|
||||||
continue
|
continue
|
||||||
|
@ -350,13 +350,29 @@ func symtab() {
|
|||||||
|
|
||||||
// pseudo-symbols to mark locations of type, string, and go string data.
|
// pseudo-symbols to mark locations of type, string, and go string data.
|
||||||
var symtype *LSym
|
var symtype *LSym
|
||||||
if !DynlinkingGo() {
|
var symtyperel *LSym
|
||||||
|
if UseRelro() && Buildmode == BuildmodeCShared {
|
||||||
s = Linklookup(Ctxt, "type.*", 0)
|
s = Linklookup(Ctxt, "type.*", 0)
|
||||||
|
|
||||||
s.Type = obj.STYPE
|
s.Type = obj.STYPE
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
symtype = s
|
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)
|
s = Linklookup(Ctxt, "go.string.*", 0)
|
||||||
@ -381,6 +397,7 @@ func symtab() {
|
|||||||
symgcbits := s
|
symgcbits := s
|
||||||
|
|
||||||
symtypelink := Linklookup(Ctxt, "runtime.typelink", 0)
|
symtypelink := Linklookup(Ctxt, "runtime.typelink", 0)
|
||||||
|
symtypelink.Type = obj.STYPELINK
|
||||||
|
|
||||||
symt = Linklookup(Ctxt, "runtime.symtab", 0)
|
symt = Linklookup(Ctxt, "runtime.symtab", 0)
|
||||||
symt.Local = true
|
symt.Local = true
|
||||||
@ -400,10 +417,15 @@ func symtab() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(s.Name, "type.") && !DynlinkingGo() {
|
if strings.HasPrefix(s.Name, "type.") && !DynlinkingGo() {
|
||||||
s.Type = obj.STYPE
|
|
||||||
s.Hide = 1
|
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.") {
|
if strings.HasPrefix(s.Name, "go.typelink.") {
|
||||||
ntypelinks++
|
ntypelinks++
|
||||||
|
BIN
src/cmd/newlink/testdata/autosection.6
vendored
BIN
src/cmd/newlink/testdata/autosection.6
vendored
Binary file not shown.
BIN
src/cmd/newlink/testdata/autoweak.6
vendored
BIN
src/cmd/newlink/testdata/autoweak.6
vendored
Binary file not shown.
BIN
src/cmd/newlink/testdata/dead.6
vendored
BIN
src/cmd/newlink/testdata/dead.6
vendored
Binary file not shown.
BIN
src/cmd/newlink/testdata/hello.6
vendored
BIN
src/cmd/newlink/testdata/hello.6
vendored
Binary file not shown.
BIN
src/cmd/newlink/testdata/layout.6
vendored
BIN
src/cmd/newlink/testdata/layout.6
vendored
Binary file not shown.
BIN
src/cmd/newlink/testdata/pclntab.6
vendored
BIN
src/cmd/newlink/testdata/pclntab.6
vendored
Binary file not shown.
Loading…
Reference in New Issue
Block a user