Commit 276803d6 authored by David Crawshaw's avatar David Crawshaw

cmd/link: introduce a rel.ro segment

When internally linking with using rel.ro sections, this segment covers
the sections. To do this, move to other read-only sections, SELFROSECT
and SMACHOPLT, out of the way.

Part of adding PIE internal linking on linux/amd64.

Change-Id: I4fb3d180e92f7e801789ab89864010faf5a2cb6d
Reviewed-on: https://go-review.googlesource.com/28538
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 13dc4d37
...@@ -384,6 +384,7 @@ const ( ...@@ -384,6 +384,7 @@ const (
STEXT STEXT
SELFRXSECT SELFRXSECT
// Read-only sections.
STYPE STYPE
SSTRING SSTRING
SGOSTRING SGOSTRING
...@@ -393,6 +394,11 @@ const ( ...@@ -393,6 +394,11 @@ const (
SRODATA SRODATA
SFUNCTAB SFUNCTAB
SELFROSECT
SMACHOPLT
// Read-only sections with relocations.
//
// Types STYPE-SFUNCTAB above are written to the .rodata section by default. // Types STYPE-SFUNCTAB above are written to the .rodata section by default.
// When linking a shared object, some conceptually "read only" types need to // When linking a shared object, some conceptually "read only" types need to
// be written to by relocations and putting them in a section called // be written to by relocations and putting them in a section called
...@@ -412,12 +418,13 @@ const ( ...@@ -412,12 +418,13 @@ const (
SRODATARELRO SRODATARELRO
SFUNCTABRELRO SFUNCTABRELRO
// Part of .data.rel.ro if it exists, otherwise part of .rodata.
STYPELINK STYPELINK
SITABLINK SITABLINK
SSYMTAB SSYMTAB
SPCLNTAB SPCLNTAB
SELFROSECT
SMACHOPLT // Writable sections.
SELFSECT SELFSECT
SMACHO SMACHO
SMACHOGOT SMACHOGOT
......
...@@ -623,10 +623,16 @@ func asmb(ctxt *ld.Link) { ...@@ -623,10 +623,16 @@ func asmb(ctxt *ld.Link) {
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f rodatblk\n", obj.Cputime()) ctxt.Logf("%5.2f rodatblk\n", obj.Cputime())
} }
ld.Cseek(int64(ld.Segrodata.Fileoff)) ld.Cseek(int64(ld.Segrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
} }
if ld.Segrelrodata.Filelen > 0 {
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f relrodatblk\n", obj.Cputime())
}
ld.Cseek(int64(ld.Segrelrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
}
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f datblk\n", obj.Cputime()) ctxt.Logf("%5.2f datblk\n", obj.Cputime())
......
...@@ -602,10 +602,16 @@ func asmb(ctxt *ld.Link) { ...@@ -602,10 +602,16 @@ func asmb(ctxt *ld.Link) {
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f rodatblk\n", obj.Cputime()) ctxt.Logf("%5.2f rodatblk\n", obj.Cputime())
} }
ld.Cseek(int64(ld.Segrodata.Fileoff)) ld.Cseek(int64(ld.Segrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
} }
if ld.Segrelrodata.Filelen > 0 {
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f relrodatblk\n", obj.Cputime())
}
ld.Cseek(int64(ld.Segrelrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
}
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f datblk\n", obj.Cputime()) ctxt.Logf("%5.2f datblk\n", obj.Cputime())
......
...@@ -411,10 +411,16 @@ func asmb(ctxt *ld.Link) { ...@@ -411,10 +411,16 @@ func asmb(ctxt *ld.Link) {
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f rodatblk\n", obj.Cputime()) ctxt.Logf("%5.2f rodatblk\n", obj.Cputime())
} }
ld.Cseek(int64(ld.Segrodata.Fileoff)) ld.Cseek(int64(ld.Segrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
} }
if ld.Segrelrodata.Filelen > 0 {
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f relrodatblk\n", obj.Cputime())
}
ld.Cseek(int64(ld.Segrelrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
}
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f datblk\n", obj.Cputime()) ctxt.Logf("%5.2f datblk\n", obj.Cputime())
......
...@@ -1508,6 +1508,33 @@ func (ctxt *Link) dodata() { ...@@ -1508,6 +1508,33 @@ func (ctxt *Link) dodata() {
} }
sect.Length = uint64(datsize) - sect.Vaddr sect.Length = uint64(datsize) - sect.Vaddr
/* read-only ELF, Mach-O sections */
for _, s := range data[obj.SELFROSECT] {
sect = addsection(segro, s.Name, 04)
sect.Align = symalign(s)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
checkdatsize(ctxt, datsize, obj.SELFROSECT)
for _, s := range data[obj.SMACHOPLT] {
sect = addsection(segro, s.Name, 04)
sect.Align = symalign(s)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
checkdatsize(ctxt, datsize, obj.SMACHOPLT)
// There is some data that are conceptually read-only but are written to by // 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 // relocations. On GNU systems, we can arrange for the dynamic linker to
// mprotect sections after relocations are applied by giving them write // mprotect sections after relocations are applied by giving them write
...@@ -1518,14 +1545,26 @@ func (ctxt *Link) dodata() { ...@@ -1518,14 +1545,26 @@ func (ctxt *Link) dodata() {
// situation. // situation.
// TODO(mwhudson): It would make sense to do this more widely, but it makes // TODO(mwhudson): It would make sense to do this more widely, but it makes
// the system linker segfault on darwin. // the system linker segfault on darwin.
relroPerms := 04 addrelrosection := func(suffix string) *Section {
relroPrefix := "" return addsection(segro, suffix, 04)
}
if UseRelro() { if UseRelro() {
relroPerms = 06 addrelrosection = func(suffix string) *Section {
relroPrefix = ".data.rel.ro" seg := &Segrelrodata
if Linkmode == LinkExternal {
// Using a separate segment with an external
// linker results in some programs moving
// their data sections unexpectedly, which
// corrupts the moduledata. So we use the
// rodata segment and let the external linker
// sort out a rel.ro segment.
seg = &Segrodata
}
return addsection(seg, ".data.rel.ro"+suffix, 06)
}
/* data only written by relocations */ /* data only written by relocations */
sect = addsection(segro, ".data.rel.ro", 06) sect = addrelrosection("")
sect.Vaddr = 0 sect.Vaddr = 0
Linklookup(ctxt, "runtime.types", 0).Sect = sect Linklookup(ctxt, "runtime.types", 0).Sect = sect
...@@ -1554,11 +1593,10 @@ func (ctxt *Link) dodata() { ...@@ -1554,11 +1593,10 @@ func (ctxt *Link) dodata() {
} }
sect.Length = uint64(datsize) - sect.Vaddr sect.Length = uint64(datsize) - sect.Vaddr
} }
/* typelink */ /* typelink */
sect = addsection(segro, relroPrefix+".typelink", relroPerms) sect = addrelrosection(".typelink")
sect.Align = dataMaxAlign[obj.STYPELINK] sect.Align = dataMaxAlign[obj.STYPELINK]
datsize = Rnd(datsize, int64(sect.Align)) datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize) sect.Vaddr = uint64(datsize)
...@@ -1575,7 +1613,7 @@ func (ctxt *Link) dodata() { ...@@ -1575,7 +1613,7 @@ func (ctxt *Link) dodata() {
sect.Length = uint64(datsize) - sect.Vaddr sect.Length = uint64(datsize) - sect.Vaddr
/* itablink */ /* itablink */
sect = addsection(segro, relroPrefix+".itablink", relroPerms) sect = addrelrosection(".itablink")
sect.Align = dataMaxAlign[obj.SITABLINK] sect.Align = dataMaxAlign[obj.SITABLINK]
datsize = Rnd(datsize, int64(sect.Align)) datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize) sect.Vaddr = uint64(datsize)
...@@ -1592,7 +1630,7 @@ func (ctxt *Link) dodata() { ...@@ -1592,7 +1630,7 @@ func (ctxt *Link) dodata() {
sect.Length = uint64(datsize) - sect.Vaddr sect.Length = uint64(datsize) - sect.Vaddr
/* gosymtab */ /* gosymtab */
sect = addsection(segro, relroPrefix+".gosymtab", relroPerms) sect = addrelrosection(".gosymtab")
sect.Align = dataMaxAlign[obj.SSYMTAB] sect.Align = dataMaxAlign[obj.SSYMTAB]
datsize = Rnd(datsize, int64(sect.Align)) datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize) sect.Vaddr = uint64(datsize)
...@@ -1609,7 +1647,7 @@ func (ctxt *Link) dodata() { ...@@ -1609,7 +1647,7 @@ func (ctxt *Link) dodata() {
sect.Length = uint64(datsize) - sect.Vaddr sect.Length = uint64(datsize) - sect.Vaddr
/* gopclntab */ /* gopclntab */
sect = addsection(segro, relroPrefix+".gopclntab", relroPerms) sect = addrelrosection(".gopclntab")
sect.Align = dataMaxAlign[obj.SPCLNTAB] sect.Align = dataMaxAlign[obj.SPCLNTAB]
datsize = Rnd(datsize, int64(sect.Align)) datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize) sect.Vaddr = uint64(datsize)
...@@ -1625,33 +1663,6 @@ func (ctxt *Link) dodata() { ...@@ -1625,33 +1663,6 @@ func (ctxt *Link) dodata() {
checkdatsize(ctxt, datsize, obj.SRODATA) checkdatsize(ctxt, datsize, obj.SRODATA)
sect.Length = uint64(datsize) - sect.Vaddr sect.Length = uint64(datsize) - sect.Vaddr
/* read-only ELF, Mach-O sections */
for _, s := range data[obj.SELFROSECT] {
sect = addsection(segro, s.Name, 04)
sect.Align = symalign(s)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
checkdatsize(ctxt, datsize, obj.SELFROSECT)
for _, s := range data[obj.SMACHOPLT] {
sect = addsection(segro, s.Name, 04)
sect.Align = symalign(s)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
checkdatsize(ctxt, datsize, obj.SMACHOPLT)
// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits. // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
if datsize != int64(uint32(datsize)) { if datsize != int64(uint32(datsize)) {
ctxt.Diag("read-only data segment too large") ctxt.Diag("read-only data segment too large")
...@@ -1711,6 +1722,10 @@ func (ctxt *Link) dodata() { ...@@ -1711,6 +1722,10 @@ func (ctxt *Link) dodata() {
sect.Extnum = int16(n) sect.Extnum = int16(n)
n++ n++
} }
for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
sect.Extnum = int16(n)
n++
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next { for sect := Segdata.Sect; sect != nil; sect = sect.Next {
sect.Extnum = int16(n) sect.Extnum = int16(n)
n++ n++
...@@ -1897,6 +1912,17 @@ func (ctxt *Link) address() { ...@@ -1897,6 +1912,17 @@ func (ctxt *Link) address() {
if Segrodata.Sect != nil { if Segrodata.Sect != nil {
// align to page boundary so as not to mix // align to page boundary so as not to mix
// rodata and executable text. // rodata and executable text.
//
// Note: gold or GNU ld will reduce the size of the executable
// file by arranging for the relro segment to end at a page
// boundary, and overlap the end of the text segment with the
// start of the relro segment in the file. The PT_LOAD segments
// will be such that the last page of the text segment will be
// mapped twice, once r-x and once starting out rw- and, after
// relocation processing, changed to r--.
//
// Ideally the last page of the text segment would not be
// writable even for this short period.
va = uint64(Rnd(int64(va), int64(*FlagRound))) va = uint64(Rnd(int64(va), int64(*FlagRound)))
Segrodata.Rwx = 04 Segrodata.Rwx = 04
...@@ -1912,6 +1938,24 @@ func (ctxt *Link) address() { ...@@ -1912,6 +1938,24 @@ func (ctxt *Link) address() {
Segrodata.Length = va - Segrodata.Vaddr Segrodata.Length = va - Segrodata.Vaddr
Segrodata.Filelen = Segrodata.Length Segrodata.Filelen = Segrodata.Length
} }
if Segrelrodata.Sect != nil {
// align to page boundary so as not to mix
// rodata, rel-ro data, and executable text.
va = uint64(Rnd(int64(va), int64(*FlagRound)))
Segrelrodata.Rwx = 06
Segrelrodata.Vaddr = va
Segrelrodata.Fileoff = va - Segrodata.Vaddr + Segrodata.Fileoff
Segrelrodata.Filelen = 0
for s := Segrelrodata.Sect; s != nil; s = s.Next {
va = uint64(Rnd(int64(va), int64(s.Align)))
s.Vaddr = va
va += s.Length
}
Segrelrodata.Length = va - Segrelrodata.Vaddr
Segrelrodata.Filelen = Segrelrodata.Length
}
va = uint64(Rnd(int64(va), int64(*FlagRound))) va = uint64(Rnd(int64(va), int64(*FlagRound)))
Segdata.Rwx = 06 Segdata.Rwx = 06
...@@ -1979,24 +2023,15 @@ func (ctxt *Link) address() { ...@@ -1979,24 +2023,15 @@ func (ctxt *Link) address() {
Segdwarf.Filelen = va - Segdwarf.Vaddr Segdwarf.Filelen = va - Segdwarf.Vaddr
text := Segtext.Sect var (
var rodata *Section text = Segtext.Sect
if Segrodata.Sect != nil { rodata = Linklookup(ctxt, "runtime.rodata", 0).Sect
rodata = Segrodata.Sect typelink = Linklookup(ctxt, "runtime.typelink", 0).Sect
} else { itablink = Linklookup(ctxt, "runtime.itablink", 0).Sect
rodata = text.Next symtab = Linklookup(ctxt, "runtime.symtab", 0).Sect
} pclntab = Linklookup(ctxt, "runtime.pclntab", 0).Sect
var relrodata *Section types = Linklookup(ctxt, "runtime.types", 0).Sect
typelink := rodata.Next )
if UseRelro() {
// There is another section (.data.rel.ro) when building a shared
// object on elf systems.
relrodata = typelink
typelink = typelink.Next
}
itablink := typelink.Next
symtab := itablink.Next
pclntab := symtab.Next
for _, s := range datap { for _, s := range datap {
ctxt.Cursym = s ctxt.Cursym = s
...@@ -2025,11 +2060,6 @@ func (ctxt *Link) address() { ...@@ -2025,11 +2060,6 @@ func (ctxt *Link) address() {
s.Value = int64(sectSym.Sect.Vaddr + 16) s.Value = int64(sectSym.Sect.Vaddr + 16)
} }
types := relrodata
if types == nil {
types = rodata
}
ctxt.xdefine("runtime.text", obj.STEXT, int64(text.Vaddr)) ctxt.xdefine("runtime.text", obj.STEXT, int64(text.Vaddr))
ctxt.xdefine("runtime.etext", obj.STEXT, int64(text.Vaddr+text.Length)) ctxt.xdefine("runtime.etext", obj.STEXT, int64(text.Vaddr+text.Length))
if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui { if Headtype == obj.Hwindows || Headtype == obj.Hwindowsgui {
......
...@@ -1783,6 +1783,9 @@ func Elfemitreloc(ctxt *Link) { ...@@ -1783,6 +1783,9 @@ func Elfemitreloc(ctxt *Link) {
for sect := Segrodata.Sect; sect != nil; sect = sect.Next { for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
elfrelocsect(ctxt, sect, datap) elfrelocsect(ctxt, sect, datap)
} }
for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
elfrelocsect(ctxt, sect, datap)
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next { for sect := Segdata.Sect; sect != nil; sect = sect.Next {
elfrelocsect(ctxt, sect, datap) elfrelocsect(ctxt, sect, datap)
} }
...@@ -2114,6 +2117,9 @@ func Asmbelfsetup(ctxt *Link) { ...@@ -2114,6 +2117,9 @@ func Asmbelfsetup(ctxt *Link) {
for sect := Segrodata.Sect; sect != nil; sect = sect.Next { for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
elfshalloc(ctxt, sect) elfshalloc(ctxt, sect)
} }
for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
elfshalloc(ctxt, sect)
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next { for sect := Segdata.Sect; sect != nil; sect = sect.Next {
elfshalloc(ctxt, sect) elfshalloc(ctxt, sect)
} }
...@@ -2283,6 +2289,9 @@ func Asmbelf(ctxt *Link, symo int64) { ...@@ -2283,6 +2289,9 @@ func Asmbelf(ctxt *Link, symo int64) {
if Segrodata.Sect != nil { if Segrodata.Sect != nil {
elfphload(ctxt, &Segrodata) elfphload(ctxt, &Segrodata)
} }
if Segrelrodata.Sect != nil {
elfphload(ctxt, &Segrelrodata)
}
elfphload(ctxt, &Segdata) elfphload(ctxt, &Segdata)
/* Dynamic linking sections */ /* Dynamic linking sections */
...@@ -2482,6 +2491,9 @@ elfobj: ...@@ -2482,6 +2491,9 @@ elfobj:
for sect := Segrodata.Sect; sect != nil; sect = sect.Next { for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
elfshbits(ctxt, sect) elfshbits(ctxt, sect)
} }
for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
elfshbits(ctxt, sect)
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next { for sect := Segdata.Sect; sect != nil; sect = sect.Next {
elfshbits(ctxt, sect) elfshbits(ctxt, sect)
} }
...@@ -2496,6 +2508,9 @@ elfobj: ...@@ -2496,6 +2508,9 @@ elfobj:
for sect := Segrodata.Sect; sect != nil; sect = sect.Next { for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
elfshreloc(ctxt, sect) elfshreloc(ctxt, sect)
} }
for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
elfshreloc(ctxt, sect)
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next { for sect := Segdata.Sect; sect != nil; sect = sect.Next {
elfshreloc(ctxt, sect) elfshreloc(ctxt, sect)
} }
......
...@@ -193,6 +193,7 @@ var ( ...@@ -193,6 +193,7 @@ var (
var ( var (
Segtext Segment Segtext Segment
Segrodata Segment Segrodata Segment
Segrelrodata Segment
Segdata Segment Segdata Segment
Segdwarf Segment Segdwarf Segment
) )
......
...@@ -203,10 +203,16 @@ func asmb(ctxt *ld.Link) { ...@@ -203,10 +203,16 @@ func asmb(ctxt *ld.Link) {
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f rodatblk\n", obj.Cputime()) ctxt.Logf("%5.2f rodatblk\n", obj.Cputime())
} }
ld.Cseek(int64(ld.Segrodata.Fileoff)) ld.Cseek(int64(ld.Segrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
} }
if ld.Segrelrodata.Filelen > 0 {
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f rodatblk\n", obj.Cputime())
}
ld.Cseek(int64(ld.Segrelrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
}
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f datblk\n", obj.Cputime()) ctxt.Logf("%5.2f datblk\n", obj.Cputime())
......
...@@ -824,10 +824,16 @@ func asmb(ctxt *ld.Link) { ...@@ -824,10 +824,16 @@ func asmb(ctxt *ld.Link) {
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f rodatblk\n", obj.Cputime()) ctxt.Logf("%5.2f rodatblk\n", obj.Cputime())
} }
ld.Cseek(int64(ld.Segrodata.Fileoff)) ld.Cseek(int64(ld.Segrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
} }
if ld.Segrelrodata.Filelen > 0 {
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f relrodatblk\n", obj.Cputime())
}
ld.Cseek(int64(ld.Segrelrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
}
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f datblk\n", obj.Cputime()) ctxt.Logf("%5.2f datblk\n", obj.Cputime())
......
...@@ -519,10 +519,16 @@ func asmb(ctxt *ld.Link) { ...@@ -519,10 +519,16 @@ func asmb(ctxt *ld.Link) {
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f rodatblk\n", obj.Cputime()) ctxt.Logf("%5.2f rodatblk\n", obj.Cputime())
} }
ld.Cseek(int64(ld.Segrodata.Fileoff)) ld.Cseek(int64(ld.Segrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
} }
if ld.Segrelrodata.Filelen > 0 {
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f rodatblk\n", obj.Cputime())
}
ld.Cseek(int64(ld.Segrelrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
}
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f datblk\n", obj.Cputime()) ctxt.Logf("%5.2f datblk\n", obj.Cputime())
......
...@@ -649,6 +649,13 @@ func asmb(ctxt *ld.Link) { ...@@ -649,6 +649,13 @@ func asmb(ctxt *ld.Link) {
ld.Cseek(int64(ld.Segrodata.Fileoff)) ld.Cseek(int64(ld.Segrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
} }
if ld.Segrelrodata.Filelen > 0 {
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f relrodatblk\n", obj.Cputime())
}
ld.Cseek(int64(ld.Segrelrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
}
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f datblk\n", obj.Cputime()) ctxt.Logf("%5.2f datblk\n", obj.Cputime())
......
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