mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/link: apply DWARF relocations while doing compression
We are preparing for applying relocations to the output buffer. However, for DWARF compression, relocations need to be applied before compression, but we don't have an output buffer at that time. We also cannot delay DWARF compression to when we mmap the output file, because we need the size of the DWARF sections to compute the file size. Instead of applying all the relocations together, we apply relocations in DWARF sections one symbol at a time, right before it is writing out for compression. As the symbol content may be in read-only memory (in the future), we use a temporary buffer for applying the relocations, and immediately write it out. If compression is not used, relocations are still applied all together. This is in preparation for mmap'ing input files read-only. Change-Id: Iae6d2dd71313897d5054bcc458d3bb78075b30c3 Reviewed-on: https://go-review.googlesource.com/c/go/+/171397 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
15a31bd9c8
commit
248444d5eb
4 changed files with 21 additions and 4 deletions
|
|
@ -2385,6 +2385,12 @@ func compressSyms(ctxt *Link, syms []*sym.Symbol) []byte {
|
||||||
log.Fatalf("NewWriterLevel failed: %s", err)
|
log.Fatalf("NewWriterLevel failed: %s", err)
|
||||||
}
|
}
|
||||||
for _, sym := range syms {
|
for _, sym := range syms {
|
||||||
|
// sym.P may be read-only. Apply relocations in a
|
||||||
|
// temporary buffer, and immediately write it out.
|
||||||
|
oldP := sym.P
|
||||||
|
ctxt.relocbuf = append(ctxt.relocbuf[:0], sym.P...)
|
||||||
|
sym.P = ctxt.relocbuf
|
||||||
|
relocsym(ctxt, sym)
|
||||||
if _, err := z.Write(sym.P); err != nil {
|
if _, err := z.Write(sym.P); err != nil {
|
||||||
log.Fatalf("compression failed: %s", err)
|
log.Fatalf("compression failed: %s", err)
|
||||||
}
|
}
|
||||||
|
|
@ -2399,6 +2405,14 @@ func compressSyms(ctxt *Link, syms []*sym.Symbol) []byte {
|
||||||
}
|
}
|
||||||
i -= int64(n)
|
i -= int64(n)
|
||||||
}
|
}
|
||||||
|
// Restore sym.P, for 1. not holding temp buffer live
|
||||||
|
// unnecessarily, 2. if compression is not beneficial,
|
||||||
|
// we'll go back to use the uncompressed contents, in
|
||||||
|
// which case we still need sym.P.
|
||||||
|
sym.P = oldP
|
||||||
|
for i := range sym.R {
|
||||||
|
sym.R[i].Done = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := z.Close(); err != nil {
|
if err := z.Close(); err != nil {
|
||||||
log.Fatalf("compression failed: %s", err)
|
log.Fatalf("compression failed: %s", err)
|
||||||
|
|
|
||||||
|
|
@ -2125,9 +2125,9 @@ func dwarfaddelfsectionsyms(ctxt *Link) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dwarfcompress compresses the DWARF sections. This must happen after
|
// dwarfcompress compresses the DWARF sections. Relocations are applied
|
||||||
// relocations are applied. After this, dwarfp will contain a
|
// on the fly. After this, dwarfp will contain a different (new) set of
|
||||||
// different (new) set of symbols, and sections may have been replaced.
|
// symbols, and sections may have been replaced.
|
||||||
func dwarfcompress(ctxt *Link) {
|
func dwarfcompress(ctxt *Link) {
|
||||||
supported := ctxt.IsELF || ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Hdarwin
|
supported := ctxt.IsELF || ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Hdarwin
|
||||||
if !ctxt.compressDWARF || !supported || ctxt.LinkMode != LinkInternal {
|
if !ctxt.compressDWARF || !supported || ctxt.LinkMode != LinkInternal {
|
||||||
|
|
@ -2161,6 +2161,7 @@ func dwarfcompress(ctxt *Link) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dwarfp = newDwarfp
|
dwarfp = newDwarfp
|
||||||
|
ctxt.relocbuf = nil // no longer needed, don't hold it live
|
||||||
|
|
||||||
// Re-compute the locations of the compressed DWARF symbols
|
// Re-compute the locations of the compressed DWARF symbols
|
||||||
// and sections, since the layout of these within the file is
|
// and sections, since the layout of these within the file is
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,8 @@ type Link struct {
|
||||||
|
|
||||||
compUnits []*compilationUnit // DWARF compilation units
|
compUnits []*compilationUnit // DWARF compilation units
|
||||||
compUnitByPackage map[*sym.Library]*compilationUnit
|
compUnitByPackage map[*sym.Library]*compilationUnit
|
||||||
|
|
||||||
|
relocbuf []byte // temporary buffer for applying relocations
|
||||||
}
|
}
|
||||||
|
|
||||||
type unresolvedSymKey struct {
|
type unresolvedSymKey struct {
|
||||||
|
|
|
||||||
|
|
@ -239,8 +239,8 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||||
ctxt.symtab()
|
ctxt.symtab()
|
||||||
ctxt.dodata()
|
ctxt.dodata()
|
||||||
order := ctxt.address()
|
order := ctxt.address()
|
||||||
ctxt.reloc()
|
|
||||||
dwarfcompress(ctxt)
|
dwarfcompress(ctxt)
|
||||||
|
ctxt.reloc()
|
||||||
filesize := ctxt.layout(order)
|
filesize := ctxt.layout(order)
|
||||||
|
|
||||||
// Write out the output file.
|
// Write out the output file.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue